前端浏览器JavaScript及CSS兼容总结


一、 getElementById

【标准参考】

getElementById 是 Document 接口提供的方法,用于获取一个元素,该方法传入的参数应该是目标元素的 id 属性的值,目标元素的 id 是一个大小写敏感的字符串,并且该 id 在文档内应该是唯一的。

【问题描述】

但是在 IE6 IE7 IE8(Q) 中,支持以 document.getElementById(elementName) 的方式获取 name 属性值为 elementName 的 A APPLET BUTTON FORM IFRAME IMG INPUT MAP META OBJECT EMBED SELECT TEXTAREA 元素,且id 是大小写不敏感的。

【造成影响】

该问题将导致在非IE浏览器内无法获取到目标元素。

【解决方案】

在使用 document.getElementById 方法获取页面元素时,应传入元素的 id 属性值,而不能使用元素的 name 属性值,且严格区分大小写。同时需注意页面中的元素的 id 属性值不能与其他元素的 name 属性值有重复。

另外,与getElementById 一样,标准的getElementsByName是区分大小写的,但是在IE下却不区分,所以我们使用时最好严格区分大小写。

二、 IE 在创建 DOM 树时会忽略某些空白字符

【标准参考】

Node(节点)不仅包括元素节点,也包含文本节点、注释节点、属性节点等等,节点的类型可以使用 nodeType 来区分。

在 HTML 源代码中,位于标签之内以及标签之间的文本(包括空白字符)将被创建为文本节点。

【问题描述】

IE 在创建 DOM 树时,会忽略某些空白字符,因此会比其他浏览器少创建一些文本节点。反过来说,同样的一篇文档,其他浏览器将比 IE 多创建一些文本节点。

【造成影响】

用户针对 IE 设计的脚本如果使用节点对象的 nodeList、firstChild、lastChild、previousSibling 或 nextSibling 方法,可能会因为此问题而无法在其他浏览器中达到相同的目的,如脚本执行出错,或对错误的目标对象进行了操作。

【解决方案】

1、没有必要时尽量去掉各标签之间的空白字符。

因为页面脚本多是对“元素节点”进行操作,因此只要保证各元素之间没有文本节点(即源代码中的标签之间没有空白字符——包括空格符、换行符、制表符),就能使上述各属性在各浏览器中的行为一致。

另外,使用脚本创建并顺次添加的元素,他们本身就是紧密相联的,各元素之间并没有文本节点,因此这种情况也不必担心上述兼容性问题,如:

2、在获取节点时做类型判断。

无法保证各元素之间没有文本节点时,则需要在针对节点的操作上添加类型判断。

另外,在非IE中,还可以使用previousElementSibling 和 nextElementSibling 获取元素节点,例如:以 Element.nextElementSibling 取得与元素 Element 的相邻的下一个元素节点。

三、document、document.body、document.documentElement对象的onscroll事件差异

【标准参考】

scroll 事件会在文档或一个元素滚动时触发。

【问题描述】

各浏览器对于 document、document.body、document.documentElement 对象的 onscroll 事件的支持存在差异

所有浏览器支持 window和普通DIV对象的 scroll 事件;

在IE、Opera 中,document和document.body 对象支持 scroll 事件。其他浏览器中不支持;

在 IE中,document.documentElement 对象支持 scroll 事件。其他浏览器中不支持。

【造成影响】

为 document、document.body、document.documentElement 对象绑定 onscroll 事件后在不同浏览器中可能不会按预期触发相应的事件处理函数。

【解决方案】

在给整个浏览器窗口绑定滚动事件 (scroll) 的时候,绑定到 window 对象上。

四、仅 IE 中的 createElement 方法支持传入 HTML String 做参数

【标准参考】

根据 W3C DOM Level2 Core 规范中的描述,Document 接口下的 createElement 方法可以创建一个元素节点对象实例。它可以传入一个字符串参数 tagName,在 HTML 中,这个参数可以是任何形式,必须是映射到可由 DOM 实现的符合规范的大写形式。即,tagName 应为一个合法的标签名。若 tagName 中出现不合法的字符,则应抛出 INVALID_CHARACTER_ERR 异常。

【问题描述】

在 IE6 IE7 IE8 中,createElement 方法不仅可以通过合法的标签名创建节点对象,还可以通过传入一段合法的 HTML 代码字符串作为参数创建节点对象。

【造成影响】

若使用了 IE 特有的通过为 createElement 传入一段合法的 HTML 代码字符串作为参数创建节点对象的方法,则在其他浏览器中将会抛出异常,并导致后续代码无法执行。

【解决方案】

对于一般的非替换元素,在各浏览器中均使用 W3C 规范中的标准的为 createElement 方法传入标签名的做法。

对于一些 IE 处理有问题的替换元素,则注意判断浏览器,针对 IE 使用其特有的通过为 createElement 传入一段合法的 HTML 代码字符串作为参数的方法,非 IE 浏览器仍然使用 W3C 规范的标准方法,例如:

不兼容代码,仅IE支持:

Var iframe = document.createElement('<iframe name="iframe">')

修改后:

var iframe = (document.all) ? document.createElement('<iframe name="iframe">') : document.createElement('iframe');

iframe.name = "iframe";

五、DOM 对象的 outerHTML、innerText、outerText 属性

【标准参考】

outerHTML 最初是由 IE 浏览器实现的私有属性,详细内容请参见 MSDN 说明:outerHTML Property。

W3C 的 HTML5 规范草案中也新加入了这个属性,它描述的是元素本身以及它的内容。当用一个字符串设置 DOM 元素的这个属性时,字符串会被当作 HTML 代码来渲染并替换这个 DOM 元素。

目前,主流浏览器中,只有 Firefox 不支持 outerHTML 属性。

【问题描述】

Firefox 不支持 DOM 对象的 outerHTML、innerText、outerText 属性

【造成影响】

在 Firefox 中使用 outerHTML、innerText、outerText 属性会使脚本程序报错。

【解决方案】

暂无,应尽量避免使用。

六、IE6 IE7 IE8 Opera 支持除 INPUT 和 BUTTON 元素以外的其他元素的 'click' 方法

【标准参考】

"click" 方法用于模拟一个鼠标点击事件,可应用于 "type" 属性值为 "button" "checkbox" "radio" "reset" "submit" 的 INPUT 元素上,其他元素的 "click" 方法规范中并没有提及。

【问题描述】

IE6 IE7 IE8 Opera 支持除 INPUT 和 BUTTON 元素以外的其他元素的 "click" 方法,这使得各浏览器对除 INPUT 和 BUTTON 元素以外的其他元素的 "click" 的支持情况存在差异。

【造成影响】

由于各浏览器对除 INPUT 和 BUTTON 元素以外的其他元素的 "click" 方法的支持情况存在差异,将导致除 INPUT 和 BUTTON 元素以外的其他元素的 "click" 方法模拟的鼠标点击所触发的函数在某些浏览器中不能得到响应。

【解决方案】

建议尽量避免对除 INPUT 和 BUTTON 元素以外的其他元素通过 "click" 方法模拟鼠标点击事件。

如需对其元素使用 "click" 方法触发 "onClick" 事件处理程序,可以通过以下两种方式解决:

* 由于大多数情况下调用 "click" 方法所实现的无非是执行某一元素所绑定的事件处理函数,因此可以直接调用该元素所对应的 "click" 事件处理函数。

* 或者使用 DOM-Level-2-Events 标准内 DocumentEvent interface 、Event interface 和 Event registration interfaces 相关定义中的 "createEvent" " initEvent" 以及 "dispatchEvent"方法建立 "click" 事件并派发出去。如:

function createEvent (eventTarget,eventName){

try{

if(eventTarget.dispatchEvent){

var evt = document.createEvent("MouseEvents");

evt.initEvent(eventName,false,true);

eventTarget.dispatchEvent(evt);

}else if(eventTarget.fireEvent){

eventTarget.fireEvent('on'+eventName);

}else{

eventTarget[ type ]();

}

}catch(e){

alert(e);

}

}

createEvent(HTMLElement,'click');

八、CSS hack的兼容总结

CSS hack是指我们为了兼容各浏览器,而使用的特别的css定义技巧。(注:不是迫不得已,应该尽量不要使用css hack,因为它的向前兼容是未知的。好的办法是学好web标准设计,从根本上进行进行兼容性设计。)下表我是结合许多资料和实践用html代码编写的表格,方便扩充和更新,但文档中不好显示,故分为两次截图:

先来个简单的区分IE浏览器和其他浏览器的例子: color:red; (所有浏览器支持) color:red\9; (IE均支持) color:red\0; (IE8支持) *color:red; (IE6/IE7支持) *+color:red; (IE7支持) _color:red; (IE6支持)