整理一下常見的IE錯誤
多年以來,IE一直都是最難于調(diào)試JavaScript 錯誤的瀏覽器。IE給出的錯誤消息一般很短又語焉不詳。而且上下文信息也很少,有時甚至一點都沒有。下面幾小節(jié)將分別探討一些在IE中難于調(diào)試的JavaScript 錯誤。
操作終止
在IE8 之前的版本中,存在一個相對于其他瀏覽器而言,最令人迷惑、討厭,也最難于調(diào)試的錯誤:操作終止(operation aborted)。在修改尚未加載完成的頁面時,就會發(fā)生操作終止錯誤。發(fā)生錯誤時,會出現(xiàn)一個模態(tài)對話框,告訴你“操作終止。"單擊確定(OK) 按鈕,則卸載整個頁面,繼而顯示一張空白屏幕;此時要進行調(diào)試非常困難。下面的示例將會導(dǎo)致操作終止錯誤。
<body>
<div>
<script>
document.body.appendChild(document.createElement("div"));
</script>
</div>
</body>
這個例子中存在的問題是:JavaScript代碼在頁面尚未加載完畢時就要修改document.body,而且script元素還不是body元素的直接子元素。準確一點說,當script節(jié)點被包含在某個元素中,而且JavaScript代碼又要使用appendChi1d、innerHTML或其他DOM 方法修改該元素的父元素或祖先元素時,將會發(fā)生操作終止錯誤(因為只能修改已經(jīng)加載完畢的元素)。
要避免這個問題,可以等到目標元素加載完畢后再對它進行操作,或者使用其他操作方法。例如,為document.body添加一個絕對定位在頁面上的覆蓋層,就是一種非常常見的操作。通常,開發(fā)人員都是使用appendChild方法來添加這個元素的,但換成使用insertBefore()方法也很容易。因此,只要修改前面例子中的一行代碼,就可以避免操作終止錯誤。
<body>
<div>
<script>
document.body.lnsertBefore(document.createElement("div"), document.body.firstChild);
</script>
</div>
</body>
在這個例子中,新的div元素被添加至document.body的開頭部分而不是末尾。因為完成這一操作所需的所有信息在腳本運行時都是已知的,所以這不會引發(fā)錯誤。
除了改變方法之外,還可以把script元素從包含元素中移出來,直接作為body的子元素。例如:
<body>
<div>
</div>
<script>
document.body.appendChild(document.createElement("div"));
</script>
</body>
這一次也不會發(fā)生錯誤,因為腳本修改的是它的直接父元素,而不再是間接的祖先元素。
在同樣的情況下,IE8不再拋出操作終止錯誤,而是拋出常規(guī)的JavaScript 錯誤,帶有如下錯誤消息:
HTML Parsing Error: unable to modify the parent Container element before the child element is closed (KB927917).
不過,雖然瀏覽器拋出的錯誤不同,但解決方案仍然是一樣的。
無效字符
根據(jù)語法,JavaScript 文件必須只包含特定的字符。在JavaScript 文件中存在無效字符時, IE會拋出無效字符( invalid character )錯誤。所謂無效字符,就是JavaScript語法中未定義的字符。例如,有一個很像減號但卻由Unicode 值8211 表示的字符( \u2013 ),就不能用作常規(guī)的減號( ASCII 編碼為45 ),因為JavaScript 語法中沒有定義該字符。這個字符通常是在Word 文檔中自動插入的。如果你的代碼是從Word 文檔中復(fù)制到文本編輯器中,然后又在IE 中運行的,那么就可能會遇到無效字符錯誤。其他瀏覽器對無效字符做出的反應(yīng)與IE類似,F(xiàn)irefox會拋出非法字符(iIlegal character) 錯誤,Safari會報告發(fā)生了語法錯誤,而Opera 則會報告發(fā)生了ReferenceError (引用錯誤)。因為它會將無效字符解釋為未定義的標識符。
未找到成員
IE中的所有DOM對象都是以COM 對象,而非原生JavaScript對象的形式實現(xiàn)的。這會導(dǎo)致一些與垃圾收集相關(guān)的非常奇怪的行為。IE中的未找到成員( Member not found )錯誤,就是由于垃圾收集例程配合錯誤所直接導(dǎo)致的。
具體來說,如果在對象被銷毀之后,又給該對象賦值,就會導(dǎo)致未找到成員錯誤。而導(dǎo)致這個錯誤的,一定是COM 對象。發(fā)生這個錯誤的最常見情形是使用event 對象的時候。IE中的event對象是window的屬性,該對象在事件發(fā)生時創(chuàng)建,在最后一個事件處理程序執(zhí)行完畢后銷毀。假設(shè)你在一個閉包中使用了event 對象,而該閉包不會立即執(zhí)行,那么在將來調(diào)用它并給event 的屬性賦值時,就會導(dǎo)致未找到成員錯誤,如下面的例子所示。
document.onclick = function () {
var event = window.event;
setTimeout(function (){
event.returnValue = false; //未找到成員錯誤
}, 1000);
};
在這段代碼中,我們將一個單擊事件處理程序指定給了文檔。在事件處理程序中,window.event被保存在event 變量中。然后,傳人setTimeout()中的閉包里又包含了event變量。當單擊事件處理程序執(zhí)行完畢后,event 對象就會被銷毀,因而閉包中引用對象的成員就成了不存在的了。換句話說,由于不能在COM對象被銷毀之后再給其成員賦值,在閉包中給returnValue 賦值就會導(dǎo)致未找到成員錯誤。
未知運行時錯誤
當使用innerHTML或outerHTML以下列方式指定HTML時,就會發(fā)生未知運行時錯誤( Unknown runtime error ):一是把塊元素插入到行內(nèi)元素時, 二是訪問表格任意部分( table 、 tbody等)的任意屬性時。例如,從技術(shù)角度說,span標簽不能包含div之類的塊級元素,因此下面的代碼就會導(dǎo)致未知運行時錯誤:
span.innerHTML = "div Hi /div"; //這里,span包含了div元素
在遇到把塊級元素插入到不恰當位置的情況時,其他瀏覽器會嘗試糾正并隱藏錯誤,而IE在這一點上反倒很較真兒。
語法錯誤
通常,只要IE一報告發(fā)生了語法錯誤( syntax error ),都可以很快找到錯誤的原因。這時候,原因可能是代碼中少了一個分號,或者花括號前后不對應(yīng)。然而,還有一種原因不十分明顯的情況需要格外注意。
如果你引用了外部的JavaScript 文件,而該文件最終并沒有返回JavaScript代碼,IE也會拋出語法錯誤。例如,script元素的src特性指向了一個HTML文件,就會導(dǎo)致語法錯誤。報告語法錯誤的位置時,通常都會說該錯誤位于腳本第一行的第一個字符處。Opera 和Safari 也會報告語法錯誤,但它們會給出導(dǎo)致問題的外部文件的信息;IE就不會給出這個信息,因此就需要我們自己重復(fù)檢查一遍引用的外部JavaScript文件。但Firefox會忽略那些被當作JavaScript 內(nèi)容嵌入到文檔中的非JavaScript文件中的解析錯誤。
在服務(wù)器端組件動態(tài)生成JavaScript 的情況下,比較容易出現(xiàn)這種錯誤。很多服務(wù)器端語言都會在發(fā)生運行錯誤時,向輸出中插入HTML代碼,而這種包含HTML的輸出很容易就會違反JavaScript語法。如果在追查語法錯誤時遇到了麻煩,我們建議你再仔細檢查一遍引用的外部文件,確保這些文件中沒有包含服務(wù)器因錯誤而插入到其中的HTML。
系統(tǒng)無法找到指定資源
系統(tǒng)無法找到指定資源(The system cannot locate the resource specified )這種說法,恐陷要算是IE給出的最有價值的錯誤消息了。在使用JavaScript 請求某個資源URL ,而該URL的長度超過了IE 對URL最長不能超過2083個字符的限制時,就會發(fā)生這個錯誤。IE不僅限制JavaScript中使用的URL的長度,而且也限制用戶在瀏覽器自身中使用的URL長度(其他瀏覽器對URL 的限制沒有這么嚴格)。IE 對URL路徑還有一個不能超過2048個字符的限制。下面的代碼將會導(dǎo)致錯誤。
function createLongUrl(url){
var s = "?";
for (var i=0, len= 2500; i < len; i++){
s += "a" ;
}
return url + s;
}
var x = new XMLHttpRequest( );
x.open("get", createLongUrl("http://www.somedomain.com/"), true);
x.send(null);
在這個例子中,XMLHttpRequest對象試圖向一個超出最大長度限制的URL發(fā)送請求。在調(diào)用open()方法時,就會發(fā)生錯誤。避免這個問題的辦法,無非就是通過給查詢字符參數(shù)起更短的名字,或者減少不必要的數(shù)據(jù),來縮短查詢字符串的長度。另外,還可以把請求方法改為POST,通過請求體而不是查詢字符串來發(fā)送數(shù)據(jù)。
相關(guān)文章
JS獲取input[file]的值并顯示在頁面的實現(xiàn)方法
下面小編就為大家分享一篇JS獲取input[file]的值并顯示在頁面的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03
JS基于對象的特性實現(xiàn)去除數(shù)組中重復(fù)項功能詳解
這篇文章主要介紹了JS基于對象的特性實現(xiàn)去除數(shù)組中重復(fù)項功能,結(jié)合實例形式較為詳細的分析了js基于key值唯一性實現(xiàn)數(shù)組去重的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
基于javascript實現(xiàn)仿百度輸入框自動匹配功能
這篇文章主要介紹了基于javascript實現(xiàn)仿百度輸入框自動匹配功能的相關(guān)資料,需要的朋友可以參考下2016-01-01
Javascript類型系統(tǒng)之String字符串類型詳解
這篇文章主要介紹了Javascript類型系統(tǒng)之String字符串類型詳解的相關(guān)資料,需要的朋友可以參考下2016-06-06
JavaScript生成器函數(shù)Generator解決異步操作問題
這篇文章主要為大家介紹了JavaScript生成器函數(shù)Generator解決異步操作問題示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10

