跨浏览器的 web 开发技巧

IBMdW 发布于 2011/06/08 09:24
阅读 450
收藏 3

文章转自 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 core 定义了对 DOM 对象的操作。

创建 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"错误,除了插入节点,还有其它几种情况,详情参看本文参考资料。

DOM HTML

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

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 文本

这是动态 HTML 经常用到的一种方法。


清单 4.插入 HTML 文本– IE
				
 document.selection.createRange().pasteHTML(html); 


清单 5.插入 HTML 文本– Firefox
				
 document.execCommand('InsertHtml','',html); 

改变 DOM 对象 class/style 属性

在 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 color

CSS 中有两种颜色表示,十六进制和 RGB 方式。事实上,在 Firefox 下,即使我们给颜色设置了十六进制值,页面的 HTML 仍将用 RGB 方式显示。

十六进制

style="COLOR: #FF0000;"

RGB 方式

style="color: RGB(255, 0, 0);"

CSS white-space

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 下显示
图 1. Firefox 下显示

图 2. IE 下显示
图 2. IE 下显示

解决方案:保留文本中第一次出现的空格,而紧跟空格之后的其余空格均由"&nbsp;"代替。这样 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 &nbsp;&nbsp;&nbsp;are &nbsp;&nbsp;many &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;white space; 
 </div> 
 </body> 

BR 问题

在 IE 中空段可以用 <p></p> 表示 . 而 Firefox 中 <p></p> 中缺省会加一个 <br>,否则无法显示。同样的 HTML 在 IE 中显示就会多出一个折行。

DOM Events

关联事件到 DOM 对象

通过 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 浏览器存在的一些差异以及如何针对这些差异进行兼容性处理。

加载中
返回顶部
顶部