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 標簽也是 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 之前,把目標節(jié)點下所有的 script 標簽移除即可,因為腳本已經(jīng)執(zhí)行過,移除它的標簽并不會造成影響,如下:
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ù)制 div 中包含 iframe,而 iframe 的頁面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會再重新執(zhí)行一次,iframe 頁本身沒問題(也不一定),但由于它操作了 parent,那么這個 parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁里的腳本自行做判斷了。
另外,cloneNode 目標節(jié)點內(nèi)包含 link 標簽的話,這個估計也會有些影響,我沒有做實驗,如果沒用的話,也是 removeChild 了之,以絕后患。
然而,script 標簽也是 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 之前,把目標節(jié)點下所有的 script 標簽移除即可,因為腳本已經(jīng)執(zhí)行過,移除它的標簽并不會造成影響,如下:
復(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ù)制 div 中包含 iframe,而 iframe 的頁面里有腳本 parent.xxx…,那么 iframe 里的這些腳本必然會再重新執(zhí)行一次,iframe 頁本身沒問題(也不一定),但由于它操作了 parent,那么這個 parent 造成的影響就難以估量了。解決方法是 cloneNode 之后,把副本里包含的 iframe 干掉,當然,如果劇情所需,iframe 不能干掉的話,就在 iframe 頁里的腳本自行做判斷了。
另外,cloneNode 目標節(jié)點內(nèi)包含 link 標簽的話,這個估計也會有些影響,我沒有做實驗,如果沒用的話,也是 removeChild 了之,以絕后患。
相關(guān)文章
微信小程序?qū)崿F(xiàn)的涂鴉功能示例【附源碼下載】
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)的涂鴉功能,涉及微信小程序事件響應(yīng)及畫筆的相關(guān)操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2018-01-01selenium 反爬蟲之跳過淘寶滑塊驗證功能的實現(xiàn)代碼
這篇文章主要介紹了selenium 反爬蟲之跳過淘寶滑塊驗證功能,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08JS與jQuery實現(xiàn)ListBox上移,下移,左移,右移操作功能示例
這篇文章主要介紹了JS與jQuery實現(xiàn)ListBox上移,下移,左移,右移操作功能,涉及javascript與jQuery的事件響應(yīng)、頁面元素動態(tài)操作等相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2018-05-05