麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 語言 > JavaScript > 正文

jQuery-1.9.1源碼分析系列(十一)DOM操作續之克隆節點

2024-05-06 16:25:41
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了jQuery-1.9.1源碼分析系列(十一)DOM操作續之克隆節點的相關資料,需要的朋友可以參考下
 

什么情況下使用到克隆節點?

  我們知道在對DOM操作過程中如果直接使用節點會出現節點隨操作而變動的情況。比如對節點使用.after/.before/.append等方法后,節點被添加到新的地方,原來的位置上的節點被移除了。有的時候需要保留原來位置上的節點,僅僅是需要一個副本添加到對應位置,這個時候克隆就有了使用場景。

  jQuery.fn.clone克隆當前匹配元素集合的一個副本,并以jQuery對象的形式返回。

  你還可以指定是否復制這些匹配元素(甚至它們的子元素)的附加數據( data()函數 )和綁定事件。

  jQueyr.fn.clone: function( withDataAndEvents, deepDataAndEvents )參數描述

a.克隆函數的底層實現步驟分解如下(jQuery.clone)

  第一步,先克隆出DOM節點。對支持正確的節點克隆(即支持elem.cloneNode并保證克隆無誤)的DOM節點直接使用cloneNode(true),否則自建一個節點來保存被克隆數據然后獲取該節點。

if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {  clone = elem.cloneNode( true );// IE<=8 不能正確克隆已分離、未知的節點//直接新建一個相同的節點,然后獲取} else {  //fragmentDiv是全局變量  fragmentDiv.innerHTML = elem.outerHTML;  fragmentDiv.removeChild( clone = fragmentDiv.firstChild );}

  第二步,如果是IE瀏覽器下,則需要通過fixCloneNodeIssues( node, destElements[i] );來逐個修正IE克隆問題。IE克隆解決方案全部包含在了fixCloneNodeIssues中,下一節詳細分析。里面的jQuery.support內容點擊這里查看更多

//針對ie克隆問題修正if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&  (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {  //在這里我們不使用Sizzle的原因是: http://jsperf.com/getall-vs-sizzle/2  destElements = getAll( clone );  srcElements = getAll( elem );  //修正所有IE克隆問題  for ( i = 0; (node = srcElements[i]) != null; ++i ) {    // Ensure that the destination node is not null; Fixes #9587    if ( destElements[i] ) {      fixCloneNodeIssues( node, destElements[i] );    }  }}

   第三步,如果要克隆緩存數據(包括普通數據和綁定事件),克隆之。

//克隆綁定的事件if ( dataAndEvents ) {  if ( deepDataAndEvents ) {    srcElements = srcElements || getAll( elem );    destElements = destElements || getAll( clone );    for ( i = 0; (node = srcElements[i]) != null; i++ ) {      cloneCopyEvent( node, destElements[i] );    }  } else {    cloneCopyEvent( elem, clone );  }}

備注:cloneCopyEvent函數中會將原節點的數據保存到克隆節點中,然后將原節點的事件綁定到新的克隆節點上

function cloneCopyEvent( src, dest ) {    if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {      return;    }    var type, i, l,    oldData = jQuery._data( src ),    curData = jQuery._data( dest, oldData ),//dest是克隆對的節點    events = oldData.events;    if ( events ) {      //保證被克隆的節點的事件對象干凈,確保沒有后面添加的事件沒有重復      delete curData.handle;      curData.events = {};      for ( type in events ) {        for ( i = 0, l = events[ type ].length; i < l; i++ ) {          jQuery.event.add( dest, type, events[ type ][ i ] );        }      }    }    // 使克隆的數據對象化    if ( curData.data ) {      curData.data = jQuery.extend( {}, curData.data );    }  }

  第四步,保護script計算歷史(全局性地標記scripts代碼段已經被執行過了),并回收內存,返回克隆節點。

destElements = getAll( clone, "script" );if ( destElements.length > 0 ) {  setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );}destElements = srcElements = node = null;return clone;

b.IE克隆問題匯總fixCloneNodeIssues(src,dest)

  src是原節點,dest是src的克隆節點。

  IE克隆問題列一下(IE8+)

  1.IE6-8當使用cloneNode會克隆事件(這些事件綁定通過attachEvent)。為保證統一性,需要清除克隆的事件,為后續統一克隆事件做準備

  // IE6-8當使用cloneNode復制事件(這些事件綁定通過attachEvent)時進入該分支  //清除原來的事件,為克隆事件做準備  if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {    data = jQuery._data( dest );    for ( e in data.events ) {      jQuery.removeEvent( dest, e, data.handle );    }    dest.removeAttribute( jQuery.expando );  }

  2.IE8-克隆腳本標簽script的時候克隆的內容結果會是空白。我們需要給他重新賦值,并確保他不會執行腳本內容。

//IE克隆腳本時內容為空白,并試圖執行新設置的文本  if ( nodeName === "script" && dest.text !== src.text ) {    disableScript( dest ).text = src.text;    restoreScript( dest );    }

  3.IE6-10不能克隆使用的classid獲取的對象元素的子節點。IE10下,如果父節點為null,則會拋出NoModificationAllowedError異常。需要使用原節點的outerHTML和innerHTML重新賦值。

 //IE6-10不能克隆使用的classid獲取的對象元素的子節點。  //IE10下,如果父節點為null,則會拋出NoModificationAllowedError異常  else if ( nodeName === "object" ) {    if ( dest.parentNode ) {      dest.outerHTML = src.outerHTML;    }    //對于IE9,這個條分支不可避免。    //IE9中克隆對象元素,上述outerHTML策略是不充分的。    //如果src具有的innerHTML并且克隆節點卻沒有,    //復制src.innerHTML到dest.innerHTML #10324    if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {      dest.innerHTML = src.innerHTML;    }  }

  4.IE6-8無法克隆一個復選框或單選按鈕的選中狀態。需要主動設置。

 // manipulation_rcheckableType = /^(?:checkbox|radio)$/i  else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {    //IE6-8無法堅持一個克隆的復選框或單選按鈕的選中狀態    //更糟的是,如果defaultChecked值沒有設置,則IE6-7無法給克隆元素選中狀態的外觀    dest.defaultChecked = dest.checked = src.checked;    ...  }

  5.當克隆select標簽時,IE6-8無法正確返回select默認選中狀態。需要主動設置。

   //當克隆選項時,IE6-8無法正確返回select默認選中狀態   else if ( nodeName === "option" ) {    dest.defaultSelected = dest.selected = src.defaultSelected;   }

  6.當克隆其他類型的input和textare標簽時,IE6-8不能正確設置defaultValue為正確的值。需要主動設置。

  //當克隆其他類型的input標簽時,IE6-8不能正確設置defaultValue為正確的值  else if ( nodeName === "input" || nodeName === "textarea" ) {    dest.defaultValue = src.defaultValue;  }

  里面用到disableScript這個函數。函數目的是改變script的type,從而保證在給script賦值后不會被作為腳本執行。這個方式我們可以借鑒

//為安全DOM操作替換/保存script節點元素type屬性function disableScript( elem ) {  var attr = elem.getAttributeNode("type");  elem.type = ( attr && attr.specified ) + "/" + elem.type;  return elem;}

以上內容是小編給大家介紹的關于jQuery-1.9.1源碼分析系列(十一)DOM操作續之克隆節點的全部敘述,希望大家喜歡。



注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 黄色片免费在线播放 | 国产二区三区四区 | 中文字幕在线看第二 | 黄色三级三级三级 | 欧美亚洲另类在线 | 日韩av成人| 成人免费乱码大片a毛片视频网站 | 成人免费看片a | 国产精品av久久久久久无 | 中文字幕在线观看国产 | 在线a| 99精品国产小情侣高潮露脸在线 | 欧美成人激情在线 | 午夜久久视频 | 亚洲性综合网 | 九九热在线视频观看这里只有精品 | 禁漫天堂久久久久久久久久 | 成人羞羞视频在线观看免费 | 一级黄色毛片播放 | 久久国产精品99国产 | 极品美女一级毛片 | 国产精品视频免费网站 | 欧美a视频 | 久草在线视频福利 | 成年人国产视频 | 在线视频 日韩 | 色婷婷久久久 | 亚洲3atv精品一区二区三区 | 91不雅视频 | 久久超 | 中文字幕 亚洲一区 | 成人在线视频在线观看 | 久久精品一区视频 | 久久不射电影网 | 国产美女的小嫩bbb图片 | 一区二区三区日韩在线 | 欧美日穴视频 | 九九热视频免费观看 | 久久激情免费视频 | 特级a欧美做爰片毛片 | 成人毛片视频在线观看 |