IE下使用cloneNode注意事項分享
更新時間:2012年11月22日 15:02:43 作者:
在開發(fā)百度“地裂特效”時,發(fā)現(xiàn)了一些匪夷所思的 bug,第一反應(yīng)是特效本身的代碼與頁面上原有的腳本發(fā)生了沖突,經(jīng)過調(diào)試發(fā)現(xiàn),問題出現(xiàn)在 cloneNode 的應(yīng)用上
cloneNode 是 HtmlElement 原型鏈上的方法,用于創(chuàng)建指定 dom 節(jié)點的拷貝,它接受一個布爾參數(shù) include_all,如果 include_all 設(shè)置為 true,則副本會帶有指定節(jié)點的所有子節(jié)點。
然而,script 標(biāo)簽也是 dom 節(jié)點,cloneNode 對其依然有效,經(jīng)實測各瀏覽器(尤其是IE)對 cloneNode 執(zhí)行結(jié)果表現(xiàn)不一致,主要現(xiàn)象為以下兩種:
IE,至少是 IE8 及以下,對某節(jié)點 cloneNode 時,如果該節(jié)點包含 script 節(jié)點,那么 script 節(jié)點的腳本內(nèi)容“有可能”會被再次執(zhí)行一次。
非 IE 瀏覽器,cloneNode 某節(jié)點,包含的 script 節(jié)點的腳本內(nèi)容不會被再次執(zhí)行。
IE 以外的瀏覽器表現(xiàn)令我很滿意,而針對于上面所述 IE 的“有可能”,還分以下兩種情況:
如果 cloneNode 一個 script 節(jié)點,無論該節(jié)點是外鏈腳本,還是內(nèi)嵌腳本,均不會被再次執(zhí)行。
如果 cloneNode 一個其它節(jié)點,該節(jié)點下包含的內(nèi)嵌腳本不會被執(zhí)行,而包含的外鏈腳本,會被再次執(zhí)行一次。
這里有一個 demo 復(fù)現(xiàn)了 IE 下 cloneNode 的這個問題。
看到這里,你是不是要被繞暈了?解決方法很簡單,不用管是什么瀏覽器,cloneNode 之前,把目標(biāo)節(jié)點下所有的 script 標(biāo)簽移除即可,因為腳本已經(jīng)執(zhí)行過,移除它的標(biāo)簽并不會造成影響,如下:
function cloneNode(dom){
var scripts = dom.getElementsByTagName("script");
for(var i = scripts - 1, s; i >= 0; i --){
s = scripts[i];
s.parentNode.removeChild(s);
}
return dom.cloneNode(true);
}
因此,我們在使用 cloneNode(true) 時一定要注意思考:所復(fù)制節(jié)點內(nèi)的所有子節(jié)點是否都是需要的?盡量把不需要的都干掉,避免造成負(fù)作用影響,再舉個例子,如果復(fù)制 div 中包含 iframe,而 iframe 的頁面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會再重新執(zhí)行一次,iframe 頁本身沒問題(也不一定),但由于它操作了 parent,那么這個 parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當(dāng)然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁里的腳本自行做判斷了。
另外,cloneNode 目標(biāo)節(jié)點內(nèi)包含 link 標(biāo)簽的話,這個估計也會有些影響,我沒有做實驗,如果沒用的話,也是 removeChild 了之,以絕后患。
然而,script 標(biāo)簽也是 dom 節(jié)點,cloneNode 對其依然有效,經(jīng)實測各瀏覽器(尤其是IE)對 cloneNode 執(zhí)行結(jié)果表現(xiàn)不一致,主要現(xiàn)象為以下兩種:
IE,至少是 IE8 及以下,對某節(jié)點 cloneNode 時,如果該節(jié)點包含 script 節(jié)點,那么 script 節(jié)點的腳本內(nèi)容“有可能”會被再次執(zhí)行一次。
非 IE 瀏覽器,cloneNode 某節(jié)點,包含的 script 節(jié)點的腳本內(nèi)容不會被再次執(zhí)行。
IE 以外的瀏覽器表現(xiàn)令我很滿意,而針對于上面所述 IE 的“有可能”,還分以下兩種情況:
如果 cloneNode 一個 script 節(jié)點,無論該節(jié)點是外鏈腳本,還是內(nèi)嵌腳本,均不會被再次執(zhí)行。
如果 cloneNode 一個其它節(jié)點,該節(jié)點下包含的內(nèi)嵌腳本不會被執(zhí)行,而包含的外鏈腳本,會被再次執(zhí)行一次。
這里有一個 demo 復(fù)現(xiàn)了 IE 下 cloneNode 的這個問題。
看到這里,你是不是要被繞暈了?解決方法很簡單,不用管是什么瀏覽器,cloneNode 之前,把目標(biāo)節(jié)點下所有的 script 標(biāo)簽移除即可,因為腳本已經(jīng)執(zhí)行過,移除它的標(biāo)簽并不會造成影響,如下:
復(fù)制代碼 代碼如下:
function cloneNode(dom){
var scripts = dom.getElementsByTagName("script");
for(var i = scripts - 1, s; i >= 0; i --){
s = scripts[i];
s.parentNode.removeChild(s);
}
return dom.cloneNode(true);
}
因此,我們在使用 cloneNode(true) 時一定要注意思考:所復(fù)制節(jié)點內(nèi)的所有子節(jié)點是否都是需要的?盡量把不需要的都干掉,避免造成負(fù)作用影響,再舉個例子,如果復(fù)制 div 中包含 iframe,而 iframe 的頁面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會再重新執(zhí)行一次,iframe 頁本身沒問題(也不一定),但由于它操作了 parent,那么這個 parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當(dāng)然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁里的腳本自行做判斷了。
另外,cloneNode 目標(biāo)節(jié)點內(nèi)包含 link 標(biāo)簽的話,這個估計也會有些影響,我沒有做實驗,如果沒用的話,也是 removeChild 了之,以絕后患。
相關(guān)文章
layui動態(tài)渲染生成select的option值方法
今天小編就為大家分享一篇layui動態(tài)渲染生成select的option值方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
兩款JS腳本判斷手機(jī)瀏覽器類型跳轉(zhuǎn)WAP手機(jī)網(wǎng)站
本文通過兩款js腳本判斷手機(jī)瀏覽器類型跳轉(zhuǎn)到wap手機(jī)網(wǎng)站,感興趣的小伙伴快來學(xué)習(xí)吧2015-10-10
js bind 函數(shù) 使用閉包保存執(zhí)行上下文
在javascript中,函數(shù)總是在一個特殊的上下文執(zhí)行(稱為執(zhí)行上下文),如果你將一個對象的函數(shù)賦值給另外一個變量的話,這個函數(shù)的執(zhí)行上下文就變?yōu)檫@個變量的上下文了。下面的一個例子能很好的說明這個問題2011-12-12
javascript提取URL的搜索字符串中的參數(shù)(自定義函數(shù)實現(xiàn))
我們經(jīng)常會看到有的頁面鏈接地址后面會跟有參數(shù),很多時候我們需要獲得這些參數(shù)的值,接下來將介紹獲取方法,感興趣的朋友可以了解系,希望本文對你有所幫助2013-01-01
JS實現(xiàn)帶有抽屜效果的產(chǎn)品類網(wǎng)站多級導(dǎo)航菜單代碼
這篇文章主要介紹了JS實現(xiàn)帶有抽屜效果的產(chǎn)品類網(wǎng)站多級導(dǎo)航菜單代碼,涉及JavaScript動態(tài)操作頁面元素屬性的技巧,整體界面效果美觀大方,具有極強(qiáng)的立體感,需要的朋友可以參考下2015-09-09
javascript超過容器后顯示省略號效果的方法(兼容一行或者多行)
下面小編就為大家?guī)硪黄猨avascript超過容器后顯示省略號效果的方法(兼容一行或者多行)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07

