【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”
文章转自 IBM developerWorks
web 开发要面临的一个重要问题是浏览器的兼容问题。虽然存在 W3C 制定的网络标准,不同的浏览器,甚至相同浏览器的不同版本行为有很大差异,开发者对于这些差异要进行特别处理。IE(Internet Explorer) 和 Firefox 作为最流行的浏览器是 web 程序开发首先要支持的两大浏览器,而很多兼容性问题被证明是 IE 特有的问题。本文中我们就针对 IE 和 Firefox 不同操作的差异列举一些处理方法。
W3C 制定了 DOM Core,DOM HTML 和 DOM Events 等标准,IE(Internet Explorer) 和 Firefox 对标准的支持程度不同。对某些标准定义,即使同样支持,行为也有差异,下面我们将分类介绍一些针对浏览器差异的处理方法。
DOM core 定义了对 DOM 对象的操作。
创建 DOM 对象,然后把这个对象插入文档是动态 HTML 最为普遍的操作。
清单 1.添加 DOM 对象
var newNode = ownerDocument.createElement("p"); parentNode.appendChild(newNode);
需要注意的是,在 IE6/IE7 上,创建 DOM 对象的 ownerDocument 一定是 DOM 对象要插入的目标 document,也就是 parentNode 所在的 document,否则插入操作会失败,抛出"Invalid Argument"错误。这点在 document 中含有 iframe 时尤其重要,因为此时会有多个 document。Firefox,IE8 没有此限制。
关于 IE6/IE7 抛出的"Invalid Argument"错误,除了插入节点,还有其它几种情况,详情参看本文参考资料。
W3C 为 DOM 对象定义了一些操作 HTML 的属性,IE 和 Firefox 并不全部支持这些属性,下表所示为 IE 和 Firefox 对几个常用 HTML 属性的支持结果 :
表 1.常用 HTML 属性
HTML 属性 IE Firefox InnerHTML Yes Yes OuterHTML Yes No InnerText Yes No OuterText Yes No TextContent No Yes
InnerHTML 是一个效率很高的批量改变文档内容的方法。需要注意的是,虽然 IE 和 Firefox 都支持这一属性,使用 InnerHTML 得到的字符串却是不同的。在 IE,innerHTML 得到的字符串,标签名大写,如果属性中没有空格,属性没有双引号,如果属性有多个值,最后一个值不加分号。
清单 2.innerHTML 值– IE
<DIV id=div2 style="display: none; margin-bottom: 0in"></DIV>
清单 3.innerHTML 值– Firefox
<div id="div2" style="display: none; margin-bottom: 0in;"></div>
在 IE 浏览器下,关于 innerHTML 赋值要注意的一个问题是,HEAD 元素不支持 innerHTML 赋值,只能通过操作 HEAD 对象改变其内容。另一个问题是,某些情况下 innerHTML 赋值可能会无效,比如将 META 元素的 HTML 片断赋值给 DIV,是无法生成 META 子节点的。
这是动态 HTML 经常用到的一种方法。
清单 4.插入 HTML 文本– IE
document.selection.createRange().pasteHTML(html);
清单 5.插入 HTML 文本– Firefox
document.execCommand('InsertHtml','',html);
在 IE 下,DOM 对象的 class 和 style 属性都不能作为普通属性处理,因此我们无法使用 setAttribute()/getAttribute() 对这两个属性进行操作。
清单 6.class 和 style 属性的读写 -IE
var class = domObj.className; var style = domObj.style.cssText; domObj.className = 'my_new_class'; domObj.style.cssText = 'display:none;'
清单 7.class 和 style 属性的读写– Firefox
var class = domObj.getAttribute('class'); var style = domObj.getAttribute('style'); domObj.setAttribute('class', 'my_new_class'); domObj.setAttribute('style', 'display:none;');
CSS 中有两种颜色表示,十六进制和 RGB 方式。事实上,在 Firefox 下,即使我们给颜色设置了十六进制值,页面的 HTML 仍将用 RGB 方式显示。
十六进制
style="COLOR: #FF0000;"
RGB 方式
style="color: RGB(255, 0, 0);"
white-space 属性设置如何处理 html 元素内的空白。
表 2.white-space 的属性值
值 描述 normal 默认。空白会被浏览器忽略。 pre 空白会被浏览器保留。其行为方式类似 HTML 中的 <pre> 标签。 nowrap 文本不会换行,文本会在在同一行上继续,直到遇到 <br> 标签为止。 pre-wrap 保留空白符序列,但是正常地进行换行。 pre-line 合并空白符序列,但是保留换行符。
当运用 pre-wrap,希望空白会被浏览器保留时,Firefox 支持此属性,但 IE 忽略。表现如下:
清单 8.HTML 清单
<body> <div> this is a white-space test! </div> <div style="white-space:pre-wrap;width:250px; border:1px solid red;"> there are many white space; </div> </body>
图 1. Firefox 下显示
图 2. IE 下显示
解决方案:保留文本中第一次出现的空格,而紧跟空格之后的其余空格均由" "代替。这样 IE 就能像 Firefox 一样正确显示了。
清单 9.处理之后的 HTML 清单
<body> <div> this is a white-space test! </div> <div style="white-space:pre-wrap;width:250px; border:1px solid red;"> there are many white space; </div> </body>
在 IE 中空段可以用 <p></p> 表示 . 而 Firefox 中 <p></p> 中缺省会加一个 <br>,否则无法显示。同样的 HTML 在 IE 中显示就会多出一个折行。
通过 JavaScript 关联事件到 DOM 对象有两种方法 :
第一种,直接给对象(object)添加事件属性。IE 可以直接赋值,Firefox 上则需要使用 attribute 赋值,直接赋值是无法得到 event 的。
清单 10.给对象添加事件属性 -IE
domObj.onkeydown = function(){ callFunction( event, param ); };
清单 11.给对象添加事件属性 -Firfox
domObj.setAttribute( 'onkeydown', 'callFunction( event, param );' );
第二种,添加 listener 给 DOM 节点。其优势在于,对同一个 event 可以有多个 event listener.
清单 12.给对象添加 listener-IE
domObj.attachEvent('onkeydown', 'callFunction') ; domObj.detachEvent('onkeydown', 'callFunction') ;
清单 13.给对象添加 listener-Firefox
domObj.addEventListener( 'keydown', 'callFunction' ,false); domObj.removeEventListener( 'keydown', 'callFunction' ,false);
- Drag & Drop 事件
IE,Firefox 都支持 drag 和 drop 事件。除了跟 IE 一样支持注册事件到目标和源 element,Firefox 还支持注册 drop 事件到 document,这个事件将会在 drop 事件完成后被调用,而 IE 不支持此注册。
- 输入法事件
在 IE 下,输入过程将连续触发 keydown,keyup 事件,其中 keydown 得到的键值总是 229,keyup 事件可以得到正确键值。而在 Firefox 中,输入开始将依次触发 keydown,compositionstart 事件,输入法结束后依次触发 compositionend,keyup 事件,输入过程中不会收到 keydown/keyup 事件。
本文详细介绍了在进行 web 开发中,IE 和 Firefox 浏览器存在的一些差异以及如何针对这些差异进行兼容性处理。