DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 整理一下常見的IE錯誤
整理一下常見的IE錯誤
編輯:關於JavaScript     

多年以來,IE一直都是最難於調試JavaScript 錯誤的浏覽器。IE給出的錯誤消息一般很短又語焉不詳。而且上下文信息也很少,有時甚至一點都沒有。下面幾小節將分別探討一些在IE中難於調試的JavaScript 錯誤。

操作終止

在IE8 之前的版本中,存在一個相對於其他浏覽器而言,最令人迷惑、討厭,也最難於調試的錯誤:操作終止(operation aborted)。在修改尚未加載完成的頁面時,就會發生操作終止錯誤。發生錯誤時,會出現一個模態對話框,告訴你“操作終止。"單擊確定(OK) 按鈕,則卸載整個頁面,繼而顯示一張空白屏幕;此時要進行調試非常困難。下面的示例將會導致操作終止錯誤。

<body>
  <div>
    <script>
      document.body.appendChild(document.createElement("div")); 
    </script>
  </div> 
</body>

這個例子中存在的問題是:JavaScript代碼在頁面尚未加載完畢時就要修改document.body,而且script元素還不是body元素的直接子元素。准確一點說,當script節點被包含在某個元素中,而且JavaScript代碼又要使用appendChi1d、innerHTML或其他DOM 方法修改該元素的父元素或祖先元素時,將會發生操作終止錯誤(因為只能修改已經加載完畢的元素)。

要避免這個問題,可以等到目標元素加載完畢後再對它進行操作,或者使用其他操作方法。例如,為document.body添加一個絕對定位在頁面上的覆蓋層,就是一種非常常見的操作。通常,開發人員都是使用appendChild方法來添加這個元素的,但換成使用insertBefore()方法也很容易。因此,只要修改前面例子中的一行代碼,就可以避免操作終止錯誤。

<body>
  <div>
    <script>
      document.body.lnsertBefore(document.createElement("div"), document.body.firstChild);
    </script>
  </div> 
</body>

在這個例子中,新的div元素被添加至document.body的開頭部分而不是末尾。因為完成這一操作所需的所有信息在腳本運行時都是已知的,所以這不會引發錯誤。

除了改變方法之外,還可以把script元素從包含元素中移出來,直接作為body的子元素。例如:

<body>
  <div>
  </div>
    <script>
      document.body.appendChild(document.createElement("div"));
    </script>
</body>

這一次也不會發生錯誤,因為腳本修改的是它的直接父元素,而不再是間接的祖先元素。

在同樣的情況下,IE8不再拋出操作終止錯誤,而是拋出常規的JavaScript 錯誤,帶有如下錯誤消息:

HTML Parsing Error: unable to modify the parent Container element before the child element is closed (KB927917).

不過,雖然浏覽器拋出的錯誤不同,但解決方案仍然是一樣的。

無效字符
根據語法,JavaScript 文件必須只包含特定的字符。在JavaScript 文件中存在無效字符時, IE會拋出無效字符( invalid character )錯誤。所謂無效字符,就是JavaScript語法中未定義的字符。例如,有一個很像減號但卻由Unicode 值8211 表示的字符( \u2013 ),就不能用作常規的減號( ASCII 編碼為45 ),因為JavaScript 語法中沒有定義該字符。這個字符通常是在Word 文檔中自動插入的。如果你的代碼是從Word 文檔中復制到文本編輯器中,然後又在IE 中運行的,那麼就可能會遇到無效字符錯誤。其他浏覽器對無效字符做出的反應與IE類似,Firefox會拋出非法字符(iIlegal character) 錯誤,Safari會報告發生了語法錯誤,而Opera 則會報告發生了ReferenceError (引用錯誤)。因為它會將無效字符解釋為未定義的標識符。

未找到成員
IE中的所有DOM對象都是以COM 對象,而非原生JavaScript對象的形式實現的。這會導致一些與垃圾收集相關的非常奇怪的行為。IE中的未找到成員( Member not found )錯誤,就是由於垃圾收集例程配合錯誤所直接導致的。

具體來說,如果在對象被銷毀之後,又給該對象賦值,就會導致未找到成員錯誤。而導致這個錯誤的,一定是COM 對象。發生這個錯誤的最常見情形是使用event 對象的時候。IE中的event對象是window的屬性,該對象在事件發生時創建,在最後一個事件處理程序執行完畢後銷毀。假設你在一個閉包中使用了event 對象,而該閉包不會立即執行,那麼在將來調用它並給event 的屬性賦值時,就會導致未找到成員錯誤,如下面的例子所示。

document.onclick = function () {
  var event = window.event;
  setTimeout(function (){
    event.returnValue = false; //未找到成員錯誤
  }, 1000);
};

在這段代碼中,我們將一個單擊事件處理程序指定給了文檔。在事件處理程序中,window.event被保存在event 變量中。然後,傳人setTimeout()中的閉包裡又包含了event變量。當單擊事件處理程序執行完畢後,event 對象就會被銷毀,因而閉包中引用對象的成員就成了不存在的了。換句話說,由於不能在COM對象被銷毀之後再給其成員賦值,在閉包中給returnValue 賦值就會導致未找到成員錯誤。

未知運行時錯誤

當使用innerHTML或outerHTML以下列方式指定HTML時,就會發生未知運行時錯誤( Unknown runtime error ):一是把塊元素插入到行內元素時, 二是訪問表格任意部分( table 、 tbody等)的任意屬性時。例如,從技術角度說,span標簽不能包含div之類的塊級元素,因此下面的代碼就會導致未知運行時錯誤:

span.innerHTML = "div Hi /div";  //這裡,span包含了div元素
在遇到把塊級元素插入到不恰當位置的情況時,其他浏覽器會嘗試糾正並隱藏錯誤,而IE在這一點上反倒很較真兒。

語法錯誤

通常,只要IE一報告發生了語法錯誤( syntax error ),都可以很快找到錯誤的原因。這時候,原因可能是代碼中少了一個分號,或者花括號前後不對應。然而,還有一種原因不十分明顯的情況需要格外注意。

如果你引用了外部的JavaScript 文件,而該文件最終並沒有返回JavaScript代碼,IE也會拋出語法錯誤。例如,script元素的src特性指向了一個HTML文件,就會導致語法錯誤。報告語法錯誤的位置時,通常都會說該錯誤位於腳本第一行的第一個字符處。Opera 和Safari 也會報告語法錯誤,但它們會給出導致問題的外部文件的信息;IE就不會給出這個信息,因此就需要我們自己重復檢查一遍引用的外部JavaScript文件。但Firefox會忽略那些被當作JavaScript 內容嵌入到文檔中的非JavaScript文件中的解析錯誤。

在服務器端組件動態生成JavaScript 的情況下,比較容易出現這種錯誤。很多服務器端語言都會在發生運行錯誤時,向輸出中插入HTML代碼,而這種包含HTML的輸出很容易就會違反JavaScript語法。如果在追查語法錯誤時遇到了麻煩,我們建議你再仔細檢查一遍引用的外部文件,確保這些文件中沒有包含服務器因錯誤而插入到其中的HTML。

系統無法找到指定資源
系統無法找到指定資源(The system cannot locate the resource specified )這種說法,恐陷要算是IE給出的最有價值的錯誤消息了。在使用JavaScript 請求某個資源URL ,而該URL的長度超過了IE 對URL最長不能超過2083個字符的限制時,就會發生這個錯誤。IE不僅限制JavaScript中使用的URL的長度,而且也限制用戶在浏覽器自身中使用的URL長度(其他浏覽器對URL 的限制沒有這麼嚴格)。IE 對URL路徑還有一個不能超過2048個字符的限制。下面的代碼將會導致錯誤。

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發送請求。在調用open()方法時,就會發生錯誤。避免這個問題的辦法,無非就是通過給查詢字符參數起更短的名字,或者減少不必要的數據,來縮短查詢字符串的長度。另外,還可以把請求方法改為POST,通過請求體而不是查詢字符串來發送數據。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved