所有類型節(jié)點都會有一個方法就是cloneNode,也就是克隆節(jié)點??寺〉牟僮饕彩俏覀兂3P枰褂玫?,本來就是一個很簡單的接口,但是還是有一些細(xì)節(jié)問題需要處理。
cloneNode不會復(fù)制javascript屬性,比如事件,這個方法只會復(fù)制特性。當(dāng)然IE有這個BUG它會復(fù)制事件處理程序。cloneNode(a)方法接受一個布爾值參數(shù),表示是否深拷貝。
true:表示執(zhí)行深拷貝,復(fù)制本節(jié)點以及整個子節(jié)點樹。
false:淺拷貝,只復(fù)制節(jié)點本身。
復(fù)制后返回的節(jié)點副本屬于文檔所有,但是并沒有父節(jié)點。除非使用 appendChild,insertChild(),replaceChild()將它添加到文檔。
關(guān)于事件的處理
IE舊版會克隆原生的事件,所以我們需要做克隆的時候先移除掉,當(dāng)然2.1.1版本是不再兼容低級版本了。所以我們考慮的是jQuery體系的處理,因為這里還沒有涉及到事件的原理,所以我們暫時先初步理解下,jQuery的事件處理是非常nice的,利用了數(shù)據(jù)緩存的機(jī)制,把數(shù)據(jù)都緩存在內(nèi)存中而不直接跟dom元素綁定,這樣的好處很多,具體我們在事件交互那一章會超詳細(xì)講解。
cloneNode(true)的時候是遍歷的節(jié)點,但是不會把對應(yīng)的事件與數(shù)據(jù)給復(fù)制,但是jQuery.clone方法克隆的時候,是會把該節(jié)點上的事件與數(shù)據(jù)給一并復(fù)制過去的,這樣的機(jī)制是建立在數(shù)據(jù)分離的基礎(chǔ)上。簡單來說,jQuery在DOM上做了一個uuid的標(biāo)記,然后把與這個dom相關(guān)聯(lián)的所有數(shù)據(jù)都放到一個內(nèi)存區(qū)域,通過這個uuid映射,這樣我們在深度拷貝 dom 的時候自然也可以把內(nèi)存的數(shù)據(jù)給復(fù)制一份了,當(dāng)然這里要注意一個問題,事件是不能被復(fù)制的,需要重新綁定了。
因為操作都是跟data_priv與data_user掛鉤的所以我模擬的話實現(xiàn)的代碼量太大了,這里就直接給大概的流程吧。
首先我們elem.cloneNode(true)直接給這個元素克隆一份,我們要做的就是把克隆后的元素加入事件與數(shù)據(jù)。
jQuery內(nèi)部的數(shù)據(jù)都緩存在data_priv中,包括事件,data_user是提供給用戶操作的,用戶的數(shù)據(jù)。
所以就需要把這個2個緩存給找出來然后混入到新的克隆節(jié)點中,jQuery都是提供接口data_priv.access,data_priv.set。
值得注意的事件的復(fù)制是需要重新jQuery.event.add綁定的,如果節(jié)點是有嵌套的話,需要遍歷每一個元素節(jié)點,在每個節(jié)點上都要處理事件與數(shù)據(jù)。
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報