日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁(yè)編程開發(fā)javascript|JQuery → jQuery內(nèi)核 DOM操作詳細(xì)教程

      jQuery內(nèi)核 DOM操作詳細(xì)教程

      相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:西西整理時(shí)間:2014/1/13 9:49:15字體大。A-A+

      作者:西西點(diǎn)擊:43次評(píng)論:0次標(biāo)簽: DOM操作

      • 類型:音頻處理大小:1M語(yǔ)言:中文 評(píng)分:5.1
      • 標(biāo)簽:
      立即下載

      domManip是什么

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

      jQuery針對(duì)DOM操作的插入的方法有大概10種

      append、prepend、before、after、replaceWith

      appendTo、prependTo、insertBefore、insertAfter、replaceAll

      分2組,上下對(duì)照,實(shí)現(xiàn)同樣的功能。主要的不同是語(yǔ)法——特別是內(nèi)容和目標(biāo)的位置

      依賴的domManip,buildFragment模塊在之前就分析過了

      在匹配元素集合中的每個(gè)元素后面插入?yún)?shù)所指定的內(nèi)容,作為其兄弟節(jié)點(diǎn)

      對(duì)于 .after(), 選擇表達(dá)式在函數(shù)的前面,參數(shù)是將要插入的內(nèi)容。

      對(duì)于.insertAfter(), 剛好相反,內(nèi)容在方法前面,它將被放在參數(shù)里元素的后面。

      after

      after: function() {    return this.domManip( arguments, function( elem ) {        if ( this.parentNode ) {            this.parentNode.insertBefore( elem, this.nextSibling );
              }
          });
      },

      之前提過了所有的方法靠this.domManip合并參數(shù)處理,內(nèi)部通過buildFragment模塊構(gòu)建文檔碎片

      然后把每一個(gè)方法的具體執(zhí)行通過回調(diào)的方式提供出來處理

      DOM操作并未提供一個(gè)直接可以在當(dāng)前節(jié)點(diǎn)后插入一個(gè)兄弟節(jié)點(diǎn)的方法,但是提供了一個(gè)類似的方法

      insertBefore() 方法:可在已有的子節(jié)點(diǎn)前插入一個(gè)新的子節(jié)點(diǎn)。語(yǔ)法 :insertBefore(newchild,refchild)

      看看jQuery如何處理的

      例如

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

      內(nèi)部就會(huì)把  '<p>Test</p>' 通過buildFragment構(gòu)建出文檔elem

      然后通過  this.parentNode.insertBefore( elem, this.nextSibling );

      這里的this 就是對(duì)應(yīng)著inner ,elem就是‘<p>Test</p>’

      看到這里就很好理解了after的實(shí)現(xiàn)了

      用原生方法簡(jiǎn)單模擬

      var  inner = document.getElementsByClassName('inner')for(var i =0 ; i<inner.length;i++){    var elem = inner[i]    var div = document.createElement('div')
          div.innerHTML = 'aaaa'
          elem.parentNode.insertBefore(div,elem.nextSibling)
      }

      insertAfter

      jQuery代碼的設(shè)計(jì)者很聰明的,都盡可能的合并相似功能的方法,代碼更加精煉美觀

      jQuery.each({
          appendTo: "append",
          prependTo: "prepend",
          insertBefore: "before",
          insertAfter: "after",
          replaceAll: "replaceWith"}, function( name, original ) {
          jQuery.fn[ name ] = function( selector ) {
                                 
          };
      });

      DEMO

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

      通過$('<p>Test</p>')構(gòu)建一個(gè)文檔,對(duì)象通過insertAfter方法插入到所有class等于inner的節(jié)點(diǎn)后

      表達(dá)的意思與after是一樣的,主要的不同是語(yǔ)法——特別是內(nèi)容和目標(biāo)的位置

      jQuery.fn[ name ] = function( selector ) {        var elems,
                  ret = [],
                  insert = jQuery( selector ),
                  last = insert.length - 1,
                  i = 0;        for ( ; i <= last; i++ ) {
                  elems = i === last ? this : this.clone( true );
                  jQuery( insert[ i ] )[ original ]( elems );            // Support: QtWebKit
                  // .get() because core_push.apply(_, arraylike) throws            core_push.apply( ret, elems.get() );
              }        return this.pushStack( ret );
          };

      看具體的實(shí)現(xiàn)方法中.insertAfter('.inner');inner其實(shí)就被當(dāng)作selector傳入進(jìn)來了

      selector可能只是字符串選擇器內(nèi)部就需要轉(zhuǎn)化,insert = jQuery( selector ),

      $('<p>Test</p>')就是構(gòu)建出來的文檔碎片節(jié)點(diǎn),那么如果賦給insert有多個(gè)的時(shí)候就需要完全克隆一份副本了,所以就直接賦給

      elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems );

      依舊是執(zhí)行after

      jQuery( insert[ i ] )[ original ]( elems );

      最終還需要返回這個(gè)構(gòu)建的新節(jié)點(diǎn)

      收集構(gòu)建的節(jié)點(diǎn)

      core_push.apply( ret, elems.get() );

      構(gòu)建一個(gè)新jQuery對(duì)象,以便實(shí)現(xiàn)鏈?zhǔn)?/p>

      this.pushStack( ret );

      可見after 與 insertAfter 本質(zhì)本質(zhì)其實(shí)都是一樣的,只是通過不同的方式調(diào)用

      before()

      根據(jù)參數(shù)設(shè)定,在匹配元素的前面插入內(nèi)容

      before: function() {        return this.domManip( arguments, function( elem ) {            if ( this.parentNode ) {                this.parentNode.insertBefore( elem, this );
                  }
              });
          },

      類似after只是替換了第二個(gè)參數(shù),改變插入的位置

      append()

      在每個(gè)匹配元素里面的末尾處插入?yún)?shù)內(nèi)容

      append: function() {    return this.domManip( arguments, function( elem ) {        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {            var target = manipulationTarget( this, elem );

                  target.appendChild( elem );
              }
          });
      },

      內(nèi)部增加節(jié)點(diǎn),直接可以調(diào)用appendChild方法

      prepend()

      將參數(shù)內(nèi)容插入到每個(gè)匹配元素的前面(元素內(nèi)部)

      prepend: function() {    return this.domManip( arguments, function( elem ) {        if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {            var target = manipulationTarget( this, elem );
                  target.insertBefore( elem, target.firstChild );
              }
          });
      },

      類似after只是替換了第二個(gè)參數(shù),改變插入的位置

      replaceWith()

      用提供的內(nèi)容替換集合中所有匹配的元素并且返回被刪除元素的集合。

      .replaceWith()可以從DOM中移除內(nèi)容,然后在這個(gè)地方插入新的內(nèi)容。請(qǐng)看下面的例子:

      <div class="container">
        <div class="inner first">Hello</div>
        <div class="inner second">And</div>
        <div class="inner third">Goodbye</div>
      </div>

      我們可以用指定的HTML替換第二個(gè) inner <div> :

      $('div.second').replaceWith('<h2>New heading</h2>');

      結(jié)果如下:

      <div class="container">
        <div class="inner first">Hello</div>
        <h2>New heading</h2>
        <div class="inner third">Goodbye</div>
      </div>

      或者我們可以選擇一個(gè)元素把它當(dāng)做替換的內(nèi)容:

      $('div.third').replaceWith($('.first'));

      結(jié)果如下:

      <div class="container">
        <div class="inner second">And</div>
        <div class="inner first">Hello</div>
      </div>

      從這個(gè)例子可以看出,用來替換的元素從老地方移到新位置,而不是復(fù)制。

      .replaceWith()方法,和大部分其他jQuery方法一樣,返回jQuery對(duì)象,所以可以和其他方法鏈接使用,但是需要注意的是:對(duì)于該方法而言,該對(duì)象指向已經(jīng)從 DOM 中被移除的對(duì)象,而不是指向替換用的對(duì)象。

      replaceWith: function() {    var
              // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
              args = jQuery.map( this, function( elem ) {            return [ elem.nextSibling, elem.parentNode ];
              }),
              i = 0;    // Make the changes, replacing each context element with the new content
          this.domManip( arguments, function( elem ) {        var next = args[ i++ ],
                  parent = args[ i++ ];        if ( parent ) {            // Don't use the snapshot next if it has moved (#13810)
                  if ( next && next.parentNode !== parent ) {
                      next = this.nextSibling;
                  }
                  jQuery( this ).remove();
                  parent.insertBefore( elem, next );
              }    // Allow new content to include elements from the context set
          }, true );    // Force removal if there was no new content (e.g., from empty arguments)
          return i ? this : this.remove();
      },

      刪除目標(biāo)節(jié)點(diǎn)

      jQuery( this ).remove();

      然后再插入一個(gè)新節(jié)點(diǎn)

      parent.insertBefore( elem, next );

      .domManip()是jQuery DOM操作的核心函數(shù)

      對(duì)封裝的節(jié)點(diǎn)操作做了參數(shù)上的校正支持,與對(duì)應(yīng)處理的調(diào)用

      append、prepend、before、after、replaceWith

      appendTo、prependTo、insertBefore、insertAfter、replaceAll

      為什么需要用這個(gè)domManip函數(shù)呢?

      我們知道節(jié)點(diǎn)操作瀏覽器提供的接口無(wú)非就是那么幾個(gè)

      appendChild()

      通過把一個(gè)節(jié)點(diǎn)增加到當(dāng)前節(jié)點(diǎn)的childNodes[]組,給文檔樹增加節(jié)點(diǎn)。

      cloneNode()

      復(fù)制當(dāng)前節(jié)點(diǎn),或者復(fù)制當(dāng)前節(jié)點(diǎn)以及它的所有子孫節(jié)點(diǎn)。

      hasChildNodes()

      如果當(dāng)前節(jié)點(diǎn)擁有子節(jié)點(diǎn),則將返回true。

      insertBefore()

      給文檔樹插入一個(gè)節(jié)點(diǎn),位置在當(dāng)前節(jié)點(diǎn)的指定子節(jié)點(diǎn)之前。如果該節(jié)點(diǎn)已經(jīng)存在,則刪除之再插入到它的位置。

      removeChild()

      從文檔樹中刪除并返回指定的子節(jié)點(diǎn)。

      replaceChild()

      從文檔樹中刪除并返回指定的子節(jié)點(diǎn),用另一個(gè)節(jié)點(diǎn)替換它。

      以上接口都有一個(gè)特性,傳入的是一個(gè)節(jié)點(diǎn)元素

      如果我們傳遞不是一個(gè)dom節(jié)點(diǎn)元素,如果是一個(gè)字符串,一個(gè)函數(shù)或者其他呢,所以針對(duì)所有接口的操作,jQuery會(huì)抽象出一種參數(shù)的處理方案

      也就是domManip存在的意義了,針對(duì)很多類似接口的參數(shù)抽象jQuery內(nèi)部有很多這樣的函數(shù)了,如之前屬性操作中的jQuery.access

      jQuery支持的參數(shù)傳遞

      jquery對(duì)接點(diǎn)才操作封裝出了一系列的接口,可以接受HTML字符串,DOM 元素,元素?cái)?shù)組,或者jQuery對(duì)象,用來插在集合中每個(gè)匹配元素的不同位置

      例如

      HTML結(jié)構(gòu)

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

      $對(duì)象

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

      回調(diào)函數(shù)

      一個(gè)返回HTML字符串,DOM 元素, 或者 jQuery 對(duì)象的函數(shù),插在每個(gè)匹配元素的后面。接收元素在集合中的索引位置作為參數(shù)。在函數(shù)中this指向元素集合中的當(dāng)前元素

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

      domManip源碼

      針對(duì)節(jié)點(diǎn)的操作有幾個(gè)重點(diǎn)的細(xì)節(jié)

      保證最終操作的永遠(yuǎn)是dom元素,瀏覽器的最終API只認(rèn)識(shí)那么幾個(gè)接口,所以如果傳遞是字符串或者其他的,當(dāng)然需要轉(zhuǎn)換

      針對(duì)節(jié)點(diǎn)的大量操作,我們肯定是需要引入文檔碎片做優(yōu)化的,這個(gè)必不可少

      domManip的結(jié)構(gòu)

      傳遞的參數(shù), 對(duì)應(yīng)的處理回調(diào),節(jié)點(diǎn)是否替換

      domManip: function( args, callback, allowIntersection ) {

      參數(shù)初始化

      iNoClone = l - 1,  是否為克隆節(jié)點(diǎn),根據(jù)后面的大意,如果當(dāng)前的jQuery對(duì)象是一個(gè)合集對(duì)象花

      那么意味著通過文檔碎片構(gòu)件出來的dom,只能是副本克隆到每一個(gè)合集對(duì)象中

      value 是第一個(gè)元素,后邊只針對(duì)args[0]進(jìn)行檢測(cè),意味著args中的元素必須是統(tǒng)一類型;

      WebKit checked屬性

      如果是回調(diào)函數(shù),或者跳過WebKit checked屬性

      在WebKit中,不能克隆包含了已選中多選按鈕的文檔碎片,這有什么問題?之后在測(cè)

      文檔碎片

      將html轉(zhuǎn)化成dom

      其實(shí)最終是通過jQuery.buildFragment方法構(gòu)件出文檔碎片

      文檔碎片的好處就不用多說了,多個(gè)繪制操作的時(shí)候合并必備

      插入頁(yè)面

      這里就用了到iNoClone了

      一看代碼就很明顯 修正了node節(jié)點(diǎn), 為什么要修正?

      因?yàn)橥ㄟ^文檔碎片構(gòu)建出來的只一樣個(gè)dom,但是jQuery是一個(gè)合集對(duì)象,所以都需要用到這個(gè)碎片了,所以你把a(bǔ)rgs append到第一個(gè)元素上了,jQuery實(shí)例的第二個(gè)元素他怎么辦?他沒有可以append的了?!所以,上來要判斷一下實(shí)例的長(zhǎng)度是不是大于1,大于1就需要cloneNode。

      callback就是對(duì)應(yīng)了所有api需要執(zhí)行的操作方法了

      jQuery2X是高級(jí)版本,所以不兼容IE6等低級(jí)瀏覽器了,自然在IE6中插入tr,如果漏掉tbody的問題也就不需要修復(fù)了

      domManip其實(shí)就只做了2事件

      第一個(gè)就是判斷3種傳遞參數(shù)所映射的對(duì)應(yīng)操作

      第二個(gè)就是通過調(diào)用jQuery.buildFragment生成文檔碎片

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無(wú)聊無(wú)聊

        熱門評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)