整理一下常见的IE错误
多年以来,IE一直都是最难于调试JavaScript 错误的浏览器 。IE给出的错误消息一般很短又语焉不详 。而且上下文信息也很少,有时甚至一点都没有 。下面几小节将分别探讨一些在IE中难于调试的JavaScript 错误 。
操作终止
在IE8 之前的版本中,存在一个相对于其他浏览器而言,最令人迷惑、讨厌,也最难于调试的错误:操作终止(operation aborted) 。在修改尚未加载完成的页面时,就会发生操作终止错误 。发生错误时 , 会出现一个模态对话框,告诉你“操作终止 。"单击确定(OK) 按钮,则卸载整个页面 , 继而显示一张空白屏幕;此时要进行调试非常困难 。下面的示例将会导致操作终止错误 。

这个例子中存在的问题是:JavaScript代码在页面尚未加载完毕时就要修改document.body,而且script元素还不是body元素的直接子元素 。准确一点说 , 当script节点被包含在某个元素中,而且JavaScript代码又要使用appendChi1d、innerHTML或其他DOM 方法修改该元素的父元素或祖先元素时 , 将会发生操作终止错误(因为只能修改已经加载完毕的元素) 。
要避免这个问题,可以等到目标元素加载完毕后再对它进行操作,或者使用其他操作方法 。例如,为document.body添加一个绝对定位在页面上的覆盖层,就是一种非常常见的操作 。通常 , 开发人员都是使用appendChild方法来添加这个元素的,但换成使用insertBefore()方法也很容易 。因此,只要修改前面例子中的一行代码,就可以避免操作终止错误 。

在这个例子中,新的div元素被添加至document.body的开头部分而不是末尾 。因为完成这一操作所需的所有信息在脚本运行时都是已知的,所以这不会引发错误 。
【整理一下常见的IE错误】除了改变方法之外,还可以把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 的属性赋值时 , 就会导致未找到成员错误,如下面的例子所示 。

在这段代码中,我们将一个单击事件处理程序指定给了文档 。在事件处理程序中,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个字符的限制 。下面的代码将会导致错误 。

在这个例子中,XMLHttpRequest对象试图向一个超出最大长度限制的URL发送请求 。在调用open()方法时,就会发生错误 。避免这个问题的办法,无非就是通过给查询字符参数起更短的名字,或者减少不必要的数据,来缩短查询字符串的长度 。另外,还可以把请求方法改为POST,通过请求体而不是查询字符串来发送数据 。
