摘要:五作用的關(guān)鍵方法,用來從目標節(jié)點克隆數(shù)據(jù)添加事件給克隆的元素注意采用數(shù)據(jù)分離的方法來保存上的事件和數(shù)據(jù),利用標記每個元素,然后在內(nèi)存上,將每個元素相關(guān)的數(shù)據(jù)放到內(nèi)存中,然后在和內(nèi)存的數(shù)據(jù)之間建立映射。
前言:這篇講完后,jQuery的文檔處理就告一段落了,有空我把這部分整合下,發(fā)一篇文章目錄。
一、示例代碼
jQuery源碼解析之clone() 這是divTwo 這是spanTwo
二、$().clone()
作用:
生成被選元素的副本,包含子節(jié)點、文本和屬性
注意:
$("div").clone(true) 表示克隆目標節(jié)點的事件和數(shù)據(jù)
$("div").clone(true,true) 表示克隆目標節(jié)點及其子節(jié)點的事件和數(shù)據(jù)
源碼:
jQuery.fn.extend({ //克隆目標節(jié)點及其子節(jié)點 //dataAndEvents是否克隆目標節(jié)點的事件和數(shù)據(jù),默認是false //deepDataAndEvents是否克隆目標節(jié)點子節(jié)點的事件和數(shù)據(jù),默認值是dataAndEvents //源碼6327行 clone: function( dataAndEvents, deepDataAndEvents ) { //默認是false dataAndEvents = dataAndEvents == null ? false : dataAndEvents; //默認是dataAndEvents deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; //循環(huán)調(diào)用jQuery.clone return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, });
解析:
可以看到,這里還是比較簡單的,需要注意的就是參數(shù)deepDataAndEvents不填的話,其值是根據(jù)參數(shù)dataAndEvents的值來定的
三、jQuery.clone()
作用同上
源碼:
jQuery.extend( { //源碼6117行 //生成被選元素的副本,包含子節(jié)點、文本和屬性 clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, //拷貝目標節(jié)點的屬性和值 //如果為true,則包括拷貝子節(jié)點的所有屬性和值 clone = elem.cloneNode( true ), //判斷elem是否脫離文檔流 inPage = jQuery.contains( elem.ownerDocument, elem ); // Fix IE cloning issues //兼容性處理,解決IE bug if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone //從目標節(jié)點克隆事件,并綁定給克隆的元素 if ( dataAndEvents ) { //克隆子節(jié)點的事件和數(shù)據(jù) if ( deepDataAndEvents ) { //源節(jié)點 srcElements = srcElements || getAll( elem ); //克隆節(jié)點 destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } //只克隆目標節(jié)點和數(shù)據(jù) else { cloneCopyEvent( elem, clone ); } } //將script標簽設(shè)為已運行 // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, })
解析:
可以看到這部分源碼主要分為三大塊:
(1)解決 IE 的 bug,主要是在fixInput()方法上進行處理
(2)從目標節(jié)點克隆數(shù)據(jù)、添加事件給克隆的元素
(3)將克隆的元素中的script標簽設(shè)為已運行
四、fixInput()
作用:
(1)解決 IE 無法保存克隆的單選、多選的狀態(tài)的 bug
(2)解決 IE 無法將克隆的選項返回至默認選項狀態(tài)的 bug
源碼:
//解決IE的bug:(1)無法保存克隆的單選、多選的狀態(tài) (2)無法將克隆的選項返回至默認選項狀態(tài) // Fix IE bugs, see support tests //源碼5937行 function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. //IE無法保存克隆的單選框和多選框的選擇狀態(tài) if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; } //IE無法將克隆的選項返回至默認選項狀態(tài) // Fails to return the selected option to the default selected state when cloning options else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } }
解析:
本質(zhì)就是將目標元素的checked屬性和defaultValue屬性手動賦值給克隆的元素。
五、cloneCopyEvent()
作用:
$().clone()的關(guān)鍵方法,用來從目標節(jié)點克隆數(shù)據(jù)、添加事件給克隆的元素
注意:
jQuery 采用數(shù)據(jù)分離的方法來保存 DOM 上的事件和數(shù)據(jù),利用 uuid 標記每個 DOM 元素,然后在內(nèi)存上,將每個 DOM 元素相關(guān)的數(shù)據(jù)放到內(nèi)存中,然后在 uuid 和內(nèi)存的數(shù)據(jù)之間建立映射。
優(yōu)點是方便復(fù)制數(shù)據(jù)。
注意:事件是不可賦值的,只能一個個添加!
示意圖:
源碼:
//src:目標元素 //dest:克隆的元素 //源碼5902行 function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } //拷貝jQuery內(nèi)部數(shù)據(jù):事件、處理程序等 // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { //private data old,即目標元素的數(shù)據(jù) //注意:jQuery是通過uuid將目標元素進行標記, //然后將與目標元素相關(guān)的數(shù)據(jù)都放到內(nèi)存中 //通過uuid和內(nèi)存的數(shù)據(jù)建立映射 //這種數(shù)據(jù)分離的做法有利于復(fù)制數(shù)據(jù),但不能復(fù)制事件 pdataOld = dataPriv.access( src ); //private data current,即為克隆的元素設(shè)置數(shù)據(jù) pdataCur = dataPriv.set( dest, pdataOld ); events = pdataOld.events; //如果事件存在 if ( events ) { //移除克隆對的元素的處理程序和事件 delete pdataCur.handle; pdataCur.events = {}; //依次為克隆的元素添加事件 //注意:事件是不能被復(fù)制的,所以需要重新綁定 for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data //拷貝用戶數(shù)據(jù) if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); //為克隆的元素設(shè)置數(shù)據(jù) dataUser.set( dest, udataCur ); } }
解析:
(1)拷貝 jQuery 內(nèi)部數(shù)據(jù)(事件、處理程序)
拷貝賦值數(shù)據(jù):
pdataOld = dataPriv.access( src ); //private data current,即為克隆的元素設(shè)置數(shù)據(jù) pdataCur = dataPriv.set( dest, pdataOld );
拷貝添加事件:
jQuery.event.add( dest, type, events[ type ][ i ] );
(2)拷貝用戶數(shù)據(jù)
dataUser.set( dest, udataCur );
六、setGlobalEval()
作用:
設(shè)置目標元素內(nèi)部的標簽為已執(zhí)行
源碼:
//設(shè)置目標元素內(nèi)部的`(完)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103852.html
摘要:一和的作用和區(qū)別觸發(fā)被選元素上的指定事件以及事件的默認行為比如表單提交不會引起事件比如表單提交的默認行為觸發(fā)所有匹配元素的指定事件只觸發(fā)第一個匹配元素的指定事件會冒泡不會冒泡二被點擊了作用看一源碼觸發(fā)事件,是自定義事件的額外參數(shù)源碼行解析本 showImg(https://segmentfault.com/img/remote/1460000019375685); 一、$().trig...
摘要:引用類型之所以會出現(xiàn)深淺拷貝的問題,實質(zhì)上是由于對基本類型和引用類型的處理不同。另外方法可以視為數(shù)組對象的淺拷貝。上面描述過的復(fù)雜問題依然存在,可以說是最簡陋但是日常工作夠用的深拷貝方式。 一直想梳理下工作中經(jīng)常會用到的深拷貝的內(nèi)容,然而遍覽了許多的文章,卻發(fā)現(xiàn)對深拷貝并沒有一個通用的完美實現(xiàn)方式。因為對深拷貝的定義不同,實現(xiàn)時的edge case過多,在深拷貝的時候會出現(xiàn)循環(huán)引用等問...
摘要:根據(jù)項目選型決定是否開啟。為了壓縮,可維護為了支持從而使用代替變量存儲防沖突會用到,形如版本號聲明最終調(diào)用的是這個原型實際上。功能檢測統(tǒng)一兼容性問題。 概覽 (function (){ (21 , 94) 定義了一些變量和函數(shù) jQuery=function(); (96 , 293) 給jQuery對象添加一些方法和屬性; (285 , 347) ...
摘要:根據(jù)項目選型決定是否開啟。為了壓縮,可維護為了支持從而使用代替變量存儲防沖突會用到,形如版本號聲明最終調(diào)用的是這個原型實際上。功能檢測統(tǒng)一兼容性問題。 概覽 (function (){ (21 , 94) 定義了一些變量和函數(shù) jQuery=function(); (96 , 293) 給jQuery對象添加一些方法和屬性; (285 , 347) ...
閱讀 3531·2021-11-24 09:39
閱讀 789·2019-08-30 14:22
閱讀 3042·2019-08-30 13:13
閱讀 2327·2019-08-29 17:06
閱讀 2928·2019-08-29 16:22
閱讀 1264·2019-08-29 10:58
閱讀 2440·2019-08-26 13:47
閱讀 1639·2019-08-26 11:39