IE下使用cloneNode注意事項(xiàng)分享
更新時(shí)間:2012年11月22日 15:02:43 作者:
在開(kāi)發(fā)百度“地裂特效”時(shí),發(fā)現(xiàn)了一些匪夷所思的 bug,第一反應(yīng)是特效本身的代碼與頁(yè)面上原有的腳本發(fā)生了沖突,經(jīng)過(guò)調(diào)試發(fā)現(xiàn),問(wèn)題出現(xiàn)在 cloneNode 的應(yīng)用上
cloneNode 是 HtmlElement 原型鏈上的方法,用于創(chuàng)建指定 dom 節(jié)點(diǎn)的拷貝,它接受一個(gè)布爾參數(shù) include_all,如果 include_all 設(shè)置為 true,則副本會(huì)帶有指定節(jié)點(diǎn)的所有子節(jié)點(diǎn)。
然而,script 標(biāo)簽也是 dom 節(jié)點(diǎn),cloneNode 對(duì)其依然有效,經(jīng)實(shí)測(cè)各瀏覽器(尤其是IE)對(duì) cloneNode 執(zhí)行結(jié)果表現(xiàn)不一致,主要現(xiàn)象為以下兩種:
IE,至少是 IE8 及以下,對(duì)某節(jié)點(diǎn) cloneNode 時(shí),如果該節(jié)點(diǎn)包含 script 節(jié)點(diǎn),那么 script 節(jié)點(diǎn)的腳本內(nèi)容“有可能”會(huì)被再次執(zhí)行一次。
非 IE 瀏覽器,cloneNode 某節(jié)點(diǎn),包含的 script 節(jié)點(diǎn)的腳本內(nèi)容不會(huì)被再次執(zhí)行。
IE 以外的瀏覽器表現(xiàn)令我很滿意,而針對(duì)于上面所述 IE 的“有可能”,還分以下兩種情況:
如果 cloneNode 一個(gè) script 節(jié)點(diǎn),無(wú)論該節(jié)點(diǎn)是外鏈腳本,還是內(nèi)嵌腳本,均不會(huì)被再次執(zhí)行。
如果 cloneNode 一個(gè)其它節(jié)點(diǎn),該節(jié)點(diǎn)下包含的內(nèi)嵌腳本不會(huì)被執(zhí)行,而包含的外鏈腳本,會(huì)被再次執(zhí)行一次。
這里有一個(gè) demo 復(fù)現(xiàn)了 IE 下 cloneNode 的這個(gè)問(wèn)題。
看到這里,你是不是要被繞暈了?解決方法很簡(jiǎn)單,不用管是什么瀏覽器,cloneNode 之前,把目標(biāo)節(jié)點(diǎn)下所有的 script 標(biāo)簽移除即可,因?yàn)槟_本已經(jīng)執(zhí)行過(guò),移除它的標(biāo)簽并不會(huì)造成影響,如下:
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);
}
因此,我們?cè)谑褂?cloneNode(true) 時(shí)一定要注意思考:所復(fù)制節(jié)點(diǎn)內(nèi)的所有子節(jié)點(diǎn)是否都是需要的?盡量把不需要的都干掉,避免造成負(fù)作用影響,再舉個(gè)例子,如果復(fù)制 div 中包含 iframe,而 iframe 的頁(yè)面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會(huì)再重新執(zhí)行一次,iframe 頁(yè)本身沒(méi)問(wèn)題(也不一定),但由于它操作了 parent,那么這個(gè) parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當(dāng)然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁(yè)里的腳本自行做判斷了。
另外,cloneNode 目標(biāo)節(jié)點(diǎn)內(nèi)包含 link 標(biāo)簽的話,這個(gè)估計(jì)也會(huì)有些影響,我沒(méi)有做實(shí)驗(yàn),如果沒(méi)用的話,也是 removeChild 了之,以絕后患。
然而,script 標(biāo)簽也是 dom 節(jié)點(diǎn),cloneNode 對(duì)其依然有效,經(jīng)實(shí)測(cè)各瀏覽器(尤其是IE)對(duì) cloneNode 執(zhí)行結(jié)果表現(xiàn)不一致,主要現(xiàn)象為以下兩種:
IE,至少是 IE8 及以下,對(duì)某節(jié)點(diǎn) cloneNode 時(shí),如果該節(jié)點(diǎn)包含 script 節(jié)點(diǎn),那么 script 節(jié)點(diǎn)的腳本內(nèi)容“有可能”會(huì)被再次執(zhí)行一次。
非 IE 瀏覽器,cloneNode 某節(jié)點(diǎn),包含的 script 節(jié)點(diǎn)的腳本內(nèi)容不會(huì)被再次執(zhí)行。
IE 以外的瀏覽器表現(xiàn)令我很滿意,而針對(duì)于上面所述 IE 的“有可能”,還分以下兩種情況:
如果 cloneNode 一個(gè) script 節(jié)點(diǎn),無(wú)論該節(jié)點(diǎn)是外鏈腳本,還是內(nèi)嵌腳本,均不會(huì)被再次執(zhí)行。
如果 cloneNode 一個(gè)其它節(jié)點(diǎn),該節(jié)點(diǎn)下包含的內(nèi)嵌腳本不會(huì)被執(zhí)行,而包含的外鏈腳本,會(huì)被再次執(zhí)行一次。
這里有一個(gè) demo 復(fù)現(xiàn)了 IE 下 cloneNode 的這個(gè)問(wèn)題。
看到這里,你是不是要被繞暈了?解決方法很簡(jiǎn)單,不用管是什么瀏覽器,cloneNode 之前,把目標(biāo)節(jié)點(diǎn)下所有的 script 標(biāo)簽移除即可,因?yàn)槟_本已經(jīng)執(zhí)行過(guò),移除它的標(biāo)簽并不會(huì)造成影響,如下:
復(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);
}
因此,我們?cè)谑褂?cloneNode(true) 時(shí)一定要注意思考:所復(fù)制節(jié)點(diǎn)內(nèi)的所有子節(jié)點(diǎn)是否都是需要的?盡量把不需要的都干掉,避免造成負(fù)作用影響,再舉個(gè)例子,如果復(fù)制 div 中包含 iframe,而 iframe 的頁(yè)面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會(huì)再重新執(zhí)行一次,iframe 頁(yè)本身沒(méi)問(wèn)題(也不一定),但由于它操作了 parent,那么這個(gè) parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當(dāng)然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁(yè)里的腳本自行做判斷了。
另外,cloneNode 目標(biāo)節(jié)點(diǎn)內(nèi)包含 link 標(biāo)簽的話,這個(gè)估計(jì)也會(huì)有些影響,我沒(méi)有做實(shí)驗(yàn),如果沒(méi)用的話,也是 removeChild 了之,以絕后患。
相關(guān)文章
微信小程序?qū)崿F(xiàn)的涂鴉功能示例【附源碼下載】
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的涂鴉功能,涉及微信小程序事件響應(yīng)及畫(huà)筆的相關(guān)操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2018-01-01完美實(shí)現(xiàn)js選項(xiàng)卡切換效果(二)
這篇文章主要為大家詳細(xì)介紹如何完美實(shí)現(xiàn)js選項(xiàng)卡切換效果,通過(guò)設(shè)置定時(shí)器實(shí)現(xiàn)延時(shí)0.5s切換選項(xiàng)卡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03selenium 反爬蟲(chóng)之跳過(guò)淘寶滑塊驗(yàn)證功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了selenium 反爬蟲(chóng)之跳過(guò)淘寶滑塊驗(yàn)證功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08怎么使用javascript深度拷貝一個(gè)數(shù)組
一般情況下,使用 “=” 可以實(shí)現(xiàn)賦值。但對(duì)于數(shù)組、對(duì)象、函數(shù)等這些引用類型的數(shù)據(jù),這個(gè)符號(hào)就不好使了。下面我們來(lái)詳細(xì)學(xué)習(xí)下吧2019-06-06JavaScript常見(jiàn)事件對(duì)象與操作實(shí)例總結(jié)
這篇文章主要介紹了JavaScript常見(jiàn)事件對(duì)象與操作,結(jié)合實(shí)例形式總結(jié)分析了javascript針對(duì)DOM、IE及跨瀏覽器事件對(duì)象的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01JS與jQuery實(shí)現(xiàn)ListBox上移,下移,左移,右移操作功能示例
這篇文章主要介紹了JS與jQuery實(shí)現(xiàn)ListBox上移,下移,左移,右移操作功能,涉及javascript與jQuery的事件響應(yīng)、頁(yè)面元素動(dòng)態(tài)操作等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-05-05JS實(shí)現(xiàn)控制表格單元格垂直對(duì)齊的方法
這篇文章主要介紹了JS實(shí)現(xiàn)控制表格單元格垂直對(duì)齊的方法,涉及javascript操作表單元素樣式的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03