1. 程式人生 > >解密jQuery核心 DOM操作的核心函式domManip

解密jQuery核心 DOM操作的核心函式domManip

domManip是什麼

dom即Dom元素,Manip是Manipulate的縮寫,連在一起就是Dom操作的意思。

.domManip()是jQuery DOM操作的核心函式

對封裝的節點操作做了引數上的校正支援,與對應處理的呼叫

append、prepend、before、after、replaceWith

appendTo、prependTo、insertBefore、insertAfter、replaceAll

image

為什麼需要用這個domManip函式呢?

我們知道節點操作瀏覽器提供的介面無非就是那麼幾個

appendChild()

通過把一個節點增加到當前節點的childNodes[]組,給文件樹增加節點。

cloneNode()

複製當前節點,或者複製當前節點以及它的所有子孫節點。

hasChildNodes()

如果當前節點擁有子節點,則將返回true。

insertBefore()

給文件樹插入一個節點,位置在當前節點的指定子節點之前。如果該節點已經存在,則刪除之再插入到它的位置。

removeChild()

從文件樹中刪除並返回指定的子節點。

replaceChild()

從文件樹中刪除並返回指定的子節點,用另一個節點替換它。

以上介面都有一個特性,傳入的是一個節點元素

如果我們傳遞不是一個dom節點元素,如果是一個字串,一個函式或者其他呢,所以針對所有介面的操作,jQuery會抽象出一種引數的處理方案

也就是domManip存在的意義了,針對很多類似介面的引數抽象jQuery內部有很多這樣的函數了,如之前屬性操作中的jQuery.access

jQuery支援的引數傳遞

jquery對接點才操作封裝出了一系列的介面,可以接受HTML字串,DOM 元素,元素陣列,或者jQuery物件,用來插在集合中每個匹配元素的不同位置

例如

HTML結構

$('.inner').after('<p>Test</p>');

$物件

$('.container').after($('h2'));

回撥函式

一個返回HTML字串,DOM 元素, 或者 jQuery 物件的函式,插在每個匹配元素的後面。接收元素在集合中的索引位置作為引數。在函式中this

指向元素集合中的當前元素

$('p').after(function() {
  return '<div>' + this.className + '</div>';
});

domManip原始碼

針對節點的操作有幾個重點的細節

  1. 保證最終操作的永遠是dom元素,瀏覽器的最終API只認識那麼幾個介面,所以如果傳遞是字串或者其他的,當然需要轉換
  2. 針對節點的大量操作,我們肯定是需要引入文件碎片做優化的,這個必不可少

domManip的結構

傳遞的引數, 對應的處理回撥,節點是否替換

domManip: function( args, callback, allowIntersection ) {

引數初始化

image

iNoClone = l - 1,  是否為克隆節點,根據後面的大意,如果當前的jQuery物件是一個合集物件花

那麼意味著通過文件碎片構件出來的dom,只能是副本克隆到每一個合集物件中

value 是第一個元素,後邊只針對args[0]進行檢測,意味著args中的元素必須是統一型別;

WebKit checked屬性

如果是回撥函式,或者跳過WebKit checked屬性

image

在WebKit中,不能克隆包含了已選中多選按鈕的文件碎片,這有什麼問題?之後在測

文件碎片

將html轉化成dom

image

其實最終是通過jQuery.buildFragment方法構件出文檔碎片

文件碎片的好處就不用多說了,多個繪製操作的時候合併必備

插入頁面

image

這裡就用了到iNoClone了

一看程式碼就很明顯 修正了node節點, 為什麼要修正?

因為通過文件碎片構建出來的只一樣個dom,但是jQuery是一個合集物件,所以都需要用到這個碎片了,所以你把args append到第一個元素上了,jQuery例項的第二個元素他怎麼辦啊?他沒有可以append的了?!所以,上來要判斷一下例項的長度是不是大於1,大於1就需要cloneNode。

callback就是對應了所有api需要執行的操作方法了

jQuery2X是高階版本,所以不相容IE6等低階瀏覽器了,自然在IE6中插入tr,如果漏掉tbody的問題也就不需要修復了

domManip其實就只做了2事件

第一個就是判斷3種傳遞引數所對映的對應操作

第二個就是通過呼叫jQuery.buildFragment生成文件碎片

DocumentFragment碎片是大家容易忽略的東西,下一章就詳細學習下~