欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

讓插入到 innerHTML 中的 script 跑起來的代碼第1/2頁

 更新時(shí)間:2007年11月20日 15:04:06   作者:  
在做 ajax 編程時(shí),我們常常需要將 xmlhttp 獲取到的頁面內(nèi)容通過 innerHTML 來賦給某個(gè)容器(比如 div、span 或者 td 等),但是這里存在一個(gè)問題,就是我們將要賦給 innerHTML 的頁面內(nèi)容如果包含有腳本程序,這些腳本程序不管是外部腳本,還是內(nèi)部腳本,可能(1)都不會(huì)被執(zhí)行。這個(gè)問題在某些時(shí)候微不足道,甚至可以忽略,但有些時(shí)候,這個(gè)問題就非常嚴(yán)重,它很可能讓我們的程序得不到預(yù)期的結(jié)果。因此我們需要解決這個(gè)問題。

如果你讀過 MSDN,你會(huì)發(fā)現(xiàn)并非所有插入到 innerHTML 中的腳本都不能執(zhí)行,如果這段腳本的 script 標(biāo)簽中包含了 defer 屬性,IE 會(huì)正確的執(zhí)行這些腳本程序。但不幸的是,Moziila/Firefox 和 Opera 可不吃這一套,不管 script 標(biāo)簽有沒有設(shè)置 defer 屬性,這些瀏覽器都不會(huì)向 IE 那樣去執(zhí)行插入到 innerHTML 中的腳本。

但不管腳本是否被執(zhí)行了,有一點(diǎn)我們可以肯定,那就是這些腳本確實(shí)被插入到了 innerHTML 中,如果不相信,你可以 alert 一下看看。但如果你真的 alert 了,你也可能會(huì)發(fā)現(xiàn)有一種例外情況存在,那就是如果腳本在 innerHTML 內(nèi)容開頭的話,那么 IE 瀏覽器將會(huì)忽略掉這段腳本,而 Moziila/Firefox 和 Opera 卻不會(huì)。

好了,問題分析的差不多了,我們來看看如何解決吧。

解決的思路其實(shí)很簡(jiǎn)單,那就是將插入到 innerHTML 中的所有腳本取出來,然后一一執(zhí)行。不過我們先要解決上面的兩個(gè)問題。

先來看第一個(gè)問題,如何避免在 IE 中重復(fù)執(zhí)行 innerHTML 中帶有 defer 屬性的腳本。這個(gè)很容易,只需要先確定瀏覽器是否是 IE,然后再檢測(cè)將要執(zhí)行的腳本是否帶有 defer 屬性即可。需要注意的是,在判斷 IE 瀏覽器時(shí),我們需要避免被 opera 的瀏覽器識(shí)別欺騙。這一點(diǎn)我們?cè)诤竺娴拇a中將會(huì)看到它是如何做的。

接下來,看 IE 忽略 innerHTML 開頭腳本的問題,這個(gè)也很容易解決。只需要在要插入到 innerHTML 中的內(nèi)容的開頭附加一段不是腳本的內(nèi)容,就可以了。但不要試圖附加一個(gè)空內(nèi)容的標(biāo)簽,或者空格、回車、換行等,這將不起作用,開頭的腳本仍然會(huì)被忽略。也不要試圖附加  ,雖然這可以讓開頭的腳本不再被忽略,但這個(gè)   仍然會(huì)影響原有內(nèi)容的顯示,雖然你可能覺得不明顯,但是對(duì)于挑剔的用戶來說,這可能是無法容忍的。因此,為了讓附加的內(nèi)容既可以起到避免開頭腳本被忽略的功能,又不會(huì)造成不良影響,我們將附加這么一段內(nèi)容:

<span style="display: none">hack ie</span>
雖然上面這段內(nèi)容有一定的長(zhǎng)度,但是它并不會(huì)顯示,而且這個(gè)插入的標(biāo)簽沒有 id 也沒有 name,所以也不會(huì)跟原來內(nèi)容中的某些標(biāo)簽的 id 或者 name 產(chǎn)生沖突。不過這里有一點(diǎn)要注意,這里也要判斷是否是 IE,然后再?zèng)Q定加不加這段內(nèi)容,因?yàn)槠渌承g覽器可能不支持 display: none 這個(gè) CSS 修飾(例如 Opera Mini),如果加上這段代碼會(huì)影響最終的顯示效果。

下面我們來看看如何取出腳本并執(zhí)行。

取出腳本很容易,只需要用 innerHTML 所在對(duì)象的 getElementsByTagName 方法就可以了,這個(gè)方法對(duì)幾乎所有的容器標(biāo)簽都管用。取出腳本以后,我們要一一判斷它們是外部腳本還是內(nèi)部腳本。

先來看外部腳本,如果是外部腳本,我們選擇了這樣一種方法,即先創(chuàng)建這個(gè)外部腳本的一個(gè)副本對(duì)象,并設(shè)置它的 defer 屬性為 true(這一點(diǎn)是為了讓 IE 瀏覽器能正確執(zhí)行),然后用 appendChild 方法將這個(gè)副本對(duì)象插入到 head 中。這里你可能會(huì)問,為什么不是插入到 innerHTML 所在的對(duì)象中呢?插入到 innerHTML 所在的對(duì)象中不是更好嗎?如果你試一下就會(huì)知道,如果插入到 innerHTML 所在的對(duì)象中,在 IE 瀏覽器中沒有問題,但是在 Mozilla/Firefox 和 Opera 瀏覽器中會(huì)有一些問題。問題是如果在 Firefox 上這樣做,瀏覽器會(huì)停止響應(yīng)(這是在 Firefox 1.5 上的測(cè)試結(jié)果,其他版本是否有此問題,尚不得知),而在 Opera 上,腳本會(huì)莫名其妙的執(zhí)行兩次(這是在 Opera 8.5 上的測(cè)試結(jié)果,其它版本的 Opera 是否由此問題,也尚不得知)。為了避免這些問題,所以我選擇了插入到 head 中。

再來看內(nèi)部腳本,內(nèi)部腳本的內(nèi)容我們可以直接用腳本對(duì)象的 text 屬性來獲取,這里我們使用腳本對(duì)象的 text 屬性而不是 innerHTML 屬性,是因?yàn)樵?nbsp;Opera 瀏覽器中,腳本對(duì)象的 innerHTML 屬性是空的,只有用 text 屬性才能獲取到腳本內(nèi)容。執(zhí)行內(nèi)部腳本直接用 eval 即可。但是腳本可能會(huì)被包含在 HTML 的注釋標(biāo)簽中,因此我們需要先將注釋標(biāo)簽去掉,不然在 IE 中會(huì)出錯(cuò)。

上面的分析看上去很完美了,但是實(shí)際上還是有問題,一個(gè)是 document.write 和 document.writeln 的問題,這個(gè)問題在 Blueidea 上,bound0 給出了一個(gè)思路,就是替換掉默認(rèn)的 document.write 和 document.writeln 方法,不過他用的是字符串替換,因此只對(duì)內(nèi)部腳本有效,對(duì)外部腳本就沒辦法了,因此我想了個(gè)更通用的辦法,就是直接把 document.write 和 document.writeln 重新定義,這樣不管內(nèi)部腳本還是外部腳本執(zhí)行的就都是我們我們自己定義的 document.write 和 document.writeln 了。不過也有副作用,就是這兩個(gè)函數(shù)在當(dāng)前頁面中就不能再像原來一樣使用了,不過這兩個(gè)函數(shù)在頁面加載完之后一般是不會(huì)再用到了,因此這里重新定義它們所帶來的副作用影響很小。但是還有個(gè)問題是,盡管這樣,我們?nèi)匀粺o法保證 document.write 或 document.writeln 輸出的內(nèi)容會(huì)顯示在最合適的位置,它只是把內(nèi)容附加到了我們放置內(nèi)容的容器中。

另一個(gè)問題是 eval 引起的問題,一個(gè)是 Blueidea 上的 hutia 說的作用域的問題,另一個(gè)問題是如果用 eval 執(zhí)行的內(nèi)部腳本的話,內(nèi)部腳本會(huì)在外部腳本加載完之前就開始執(zhí)行了。要解決這個(gè)兩個(gè)問題可以采用 window.setTimeout 這個(gè)函數(shù),讓每個(gè)腳本都延時(shí)一段后再執(zhí)行,外部腳本延時(shí)時(shí)間可以設(shè)的較長(zhǎng),以保證其能夠完全加載,而內(nèi)部腳本則可以設(shè)置為很短,因?yàn)橐粋€(gè)腳本執(zhí)行的時(shí)間通常是很短的,這樣既可以保證不會(huì)改變作用域,又可以基本保證腳本執(zhí)行順序不會(huì)改變了(這種方法對(duì)于保證執(zhí)行順序上也不一定會(huì) 100% 有效,如果網(wǎng)絡(luò)非常繁忙,外部腳本可能在設(shè)置的時(shí)間內(nèi)加載不完,但至少比直接用 eval 的時(shí)候好多了)。

——————————–
(1) 注:在這里,我們用了限定詞“可能”,因?yàn)橛幸环N情況,腳本會(huì)被執(zhí)行,在下文中你將會(huì)看到這種情況。

相關(guān)文章

  • js屏蔽退格鍵(backspace或者叫后退鍵與F5)

    js屏蔽退格鍵(backspace或者叫后退鍵與F5)

    今天有工作人員反饋后臺(tái)編輯文章的時(shí)候,多按了幾下退格鍵,然后當(dāng)前編輯的頁面都返回到上一頁了,導(dǎo)致剛剛添加的內(nèi)容全部丟失,今天正好有空給整理一下
    2019-02-02
  • JavaScrip數(shù)組去重操作實(shí)例小結(jié)

    JavaScrip數(shù)組去重操作實(shí)例小結(jié)

    這篇文章主要介紹了JavaScrip數(shù)組去重操作,結(jié)合實(shí)例形式總結(jié)分析了javascript針對(duì)數(shù)組的遍歷、判斷、去重等相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • 原生JS實(shí)現(xiàn)DOM加載完成馬上執(zhí)行JS代碼的方法

    原生JS實(shí)現(xiàn)DOM加載完成馬上執(zhí)行JS代碼的方法

    今天小編就為大家分享一篇原生JS實(shí)現(xiàn)DOM加載完成馬上執(zhí)行JS代碼的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • js幾個(gè)不錯(cuò)的函數(shù) $$()

    js幾個(gè)不錯(cuò)的函數(shù) $$()

    js幾個(gè)不錯(cuò)的函數(shù) $$()...
    2006-10-10
  • javascript遞歸回溯法解八皇后問題

    javascript遞歸回溯法解八皇后問題

    網(wǎng)上看到許多關(guān)于八皇后算法的文章,很少能看到使用javascript來實(shí)現(xiàn)的,今天就給大家使用javascript來解決下這個(gè)問題,有需要的小伙伴可以參考下。
    2015-04-04
  • 用headjs來管理和加載js 提高網(wǎng)站加載速度

    用headjs來管理和加載js 提高網(wǎng)站加載速度

    headjs其實(shí)是一整套的工具,本文介紹的是它其中的Javascript Loader功能。需要的朋友可以參考下
    2016-11-11
  • JavaScript如何禁止Backspace鍵

    JavaScript如何禁止Backspace鍵

    這篇文章主要介紹了JavaScript如何禁止Backspace鍵,可以幫助大家解決“只讀輸入框在IE下按下Backspace鍵回退到前一個(gè)頁面”的問題,感興趣的小伙伴們可以參考一下
    2015-12-12
  • JS實(shí)現(xiàn)五星好評(píng)效果

    JS實(shí)現(xiàn)五星好評(píng)效果

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)五星好評(píng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JS+Canvas實(shí)現(xiàn)的俄羅斯方塊游戲完整實(shí)例

    JS+Canvas實(shí)現(xiàn)的俄羅斯方塊游戲完整實(shí)例

    這篇文章主要介紹了JS+Canvas實(shí)現(xiàn)的俄羅斯方塊游戲,結(jié)合完整實(shí)例形式分析了Canvas技術(shù)實(shí)現(xiàn)俄羅斯方塊游戲的步驟、技術(shù)難點(diǎn)與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-12-12
  • js方法數(shù)據(jù)驗(yàn)證的簡(jiǎn)單實(shí)例

    js方法數(shù)據(jù)驗(yàn)證的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄猨s方法數(shù)據(jù)驗(yàn)證的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09

最新評(píng)論