2011-07-22 32 views
0

我使用document.write()只是調試一些代碼,並發現在IE8中的一些非常奇怪的行爲。是我嗎,還是這是一個錯誤?document.write()和document.images [i] .width在IE8中失敗!

只有4 img元件A頁:

<img src="img/one.jpg" width="100" height="75" alt="1st Demo Image" title=""> 
<img src="img/two.jpg" width="100" height="75" alt="2nd Demo Image" title=""> 
<img src="img/three.jpg" width="100" height="75" alt="3rd Demo Image" title=""> 
<img src="img/four.jpg" width="100" height="75" alt="4th Demo Image" title=""> 

通過document.images的HTMLCollection循環,以輸出使用所述document.write()各圖像的寬度屬性的值(或document.writeln()沒關係):

for (var i=0; i<document.images.length; i++) { 
    document.writeln(i + ' - ' + document.images[i]['width']); 
} 

除IE8外,所有瀏覽器都按預期輸出4行。但是,IE8只輸出第一行,用於第一個圖像!爲什麼?!

循環「循環」確定。您可以使用alert()輸出width屬性,並在IE8中獲得4個警報,但仍然只有第一行使用document.write()輸出!

for (var i=0; i<document.images.length; i++) { 
    document.writeln(i + ' - ' + document.images[i]['width']); 
    alert(i + ' - ' + document.images[i]['width']); // Alerts 4 times 
} 

'高度'屬性也是一個問題。其他屬性,如'src','alt',甚至像'monkey'這樣的未定義的屬性輸出OK;爲您提供不要在循環中也有一個alert()

如果你將document.write()從循環中取出,追加到循環中的字符串,並且在循環後只有1 document.write()以輸出字符串,那麼就是OK。

通過NodeList訪問寬度屬性也是一個問題... document.getElementsByTagName('img')[i].width - 與上面相同的問題,只輸出第一行!

任何想法?或者它只是一個'IE8'的怪癖!?

EDIT#1

此代碼是在事件中運行,像onload。它正在頁面正文的腳本元素中運行,而頁面正在被解析。是的,您不能在事件中調用document.write(),希望影響當前文檔,因爲文檔解析可能已完成,並且調用document.write()將隱式地打開新文檔。

此問題只有體現在IE8上。
IE6,IE7,IE9和其他所有測試過的瀏覽器都按預期工作。

編輯#2 - 發現原因(但不是這個原因)

好吧,我想我的測試頁面很簡單 - 它似乎是不太夠簡單!我想我已經找到了這個問題的原因(不是原因),但不幸的是這是它變得更加怪異的地方!

問題似乎是,如果生成輸出的腳本元素直接在display:block的元素內。這並不一定是塊級元素(如divpre)的元素,但是任何元素都是display:block!塊容器和腳本元素之間不能有空格。

所以,這個確切的代碼(身體標記之間)再現了IE8這個問題:

<img src="img/one.jpg" width="100" height="75" alt="1st Demo Image"> 
<img src="img/two.jpg" width="100" height="75" alt="2nd Demo Image"> 
<img src="img/three.jpg" width="100" height="75" alt="3rd Demo Image"> 
<img src="img/four.jpg" width="100" height="75" alt="4th Demo Image"> 
<pre><script type="text/javascript"> 
// Only the first line is output in IE8, other browsers OK 
for (var i=0; i<document.images.length; i++) { 
    document.writeln(i + ' - ' + document.images[i]['width']); 
} 
</script></pre> 

但是,如果你是開<pre>標籤問題消失後放只是一個單一的空間(但你會在輸出中獲得額外的空間)!

而且,這似乎隻影響widthheight(數字?)屬性!

回答

1

假設你的document.write清除文檔(如果是依據規範或實現的依賴關係,那麼它將調用document.open()來清除文檔,包括圖像),我將清除該文檔(我是not sure)。因此,在第一個document.write()調用清除文檔後,不再有圖像,因此當循環繼續訪問document.images[1]時,該項目不再可用。

這就解釋了爲什麼其他方法有效,因爲警告或連接字符串不會清除文檔。

+0

我做了這個奇蹟,但'document.write()的'不是一個事件處理程序,它是在頁面的主體文件已經完全寫入之前。輸出其他屬性工作正常。用'document.write()'輸出'alert()'確實會產生4個警報,如果第一個write()清除了文檔,它大概不會這樣做。 – MrWhite

+0

@ w3d,如果文檔尚未寫入,則不應嘗試訪問其內部結構... – davin

+0

這是在關閉'body'標記之前出現的測試/調試代碼,所以DOM _應該足夠完整爲此代碼工作正常。事實上,這似乎並不是一個DOM問題。我已經更新了這個問題(編輯#2),這個問題似乎觸發了這個_phenomenon_。這隻會影響IE8。 – MrWhite

1

如果在文檔載入後運行,文檔將覆蓋主體的內容。

試試這個:

var htm = []; 
for (var i=0; i<document.images.length; i++) { 
    htm.push(i + ' - ' + document.images[i]['width']); 
} 

document.write(htm.join('')); 
+0

是的,對不起,我最初從我的問題中忽略了這一點。代碼沒有在事件中運行。正在解析文檔時,它正在頁面中運行。正如我的問題所述,如果我在循環中連接一個字符串並使用'document.write()'輸出循環外部,那麼它也可以工作,但我喜歡數組的想法 - 謝謝。 – MrWhite