浏览器市场的百花争艳既打破了IE一家独霸的垄断局面也给网页开发者带来不小的麻烦,IE、FireFox、Opera、Safari……还有新秀Chrome...昨日黄花Netscape...Oh My God!究竟哪款浏览器可以完美展现我的网页效果?我那制作精美的网页在哪款浏览器上又糟糕的一塌糊涂?本文仅关注占浏览器市场份额绝大部分的IE与FireFox对网页开发中的兼容性问题,文中所涉及经验部分为笔者在实际开发中总结、另有较多信息从大量互联网资料中整理所得,并未一一测试验证。本文作为教程还远远不够,权且当作经验总结以供大家参考。
一、 JS与DOM的兼容性:
(一) DOM节点的访问:
1. 以前对DOM节点访问一般用“document.All.元素ID属性值”或者“document.元素ID属性值”这种简化的方法,在FireFox中有时不支持此方法。
解决办法:标准的方法为“document.getElementById(‘元素ID属性值’)”或者“document.getElementByName(‘元素Name属性值’)[0]”或者“document.getElementByTagName(‘元素标签名’)[0]”;
2. 集合类对象的()与[]的问题:以前的代码中很多集合类对象的访问使用(),IE可以正常解析,FireFox不支持。
解决办法:改用[]作为下标符号。如:document.Forms(‘FormName’)改为document.Forms[‘FormName’];又如:document.getElementsByName(‘元素Name属性值’)(1)改为document.getElementsByName(‘元素Name属性值’)[1];
3. document.Form.Item的问题:FireFox不能正常解析形如:document.FormName.Item("ItemName")这样的语句,但IE与FireFox都支持document.FormName.Elements["ElementName"]。
解决办法:改用如下语句形式:document.FormName.Elements["ElementName"];
4. 在IE中,可以利用eval(‘元素ID属性值’)的方法取得改HTML对象,FireFox不支持此种对象访问方法。
解决办法:用“document.getElementById(‘元素ID属性值’)”的方法取得对象;
5. 在IE中可以通过ID属性值或者Name属性访问这个Frame对象,而FireFox只可以通过Name属性来访问这个Frame对象;
IE和FireFox均可通过window.document. getElementById(‘FrameId属性值’)来访问这个Frame对象
6. 在IE中body对象要在<body>标签完全读入才会存在,而在FireFox中一开始就存在
7. 在IE中input标签的type属性是只读的,但在FireFox中是可读写的
8. 在IE中getElementsByName()、document.all[name]均不能用来取得div元素
9. IE,FireFox以及其它浏览器对于Table标签的操作都各不相同,在IE中不允许对Table和TR的innerHTML赋值,使用JS增加一个TR时,使用appendChild方法也不管用。
解决办法:
//向Table追加一个空行:
var row = otable.insertRow(-1);
var cell = document.createElement("td");
cell.innerHTML = " ";
cell.className = "XXXX";
row.appendChild(cell);
10. 在FireFox节点中没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)
11. IE或者FireFox2.0.x下,可以使用window.location或window.location.href;但在FireFox1.5下,只能使用window.location
解决方法:使用window.location来代替window.location.href
12. IE与FireFox的访问父元素有区别,IE为Obj.ParentElement属性;FireFox为Obj.ParentNode属性
解决办法:因为FireFox与IE都支持DOM,因此统一用ParentNode属性
13. FireFox不支持元素的innerText属性,需用textContent
解决办法:
if(navigator.appName.indexOf("Explorer") > -1){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = "my text";
}
14. FireFox不支持元素的HtmlText属性
解决办法:
rng = document.createRange();
el = document.getElementById(ElementId);
rng.setStartBefore(el);
htmlFrag = rng.createContextualFragment(content);
while (el.hasChildNodes()){ //清除原有内容,加入新内容
el.RemoveChild(el.LastChild);
}
el.AppendChild(htmlFrag);
15. 在IE下可以用<Img Id="pic" OnClick="this.src= ‘aa.php’" src="aa.php" style="cursor: pointer"/> 可以刷新图片,但在FireFox下由于缓存问题不行。
解决办法:
在地址后面加个随机数:编辑onclick事件代码如下:"this.src=this.src+’?’+Math.random()"
16. 在访问某一节点如childNodes[i]时,要获得该节点的值而这个值是<![CDATA[]]类型,那么在IE中可支持这样访问childNodes[i].text或childNodes[i].firstChild.nodeValue;在FireFox只支持childNodes[i].firstChild.nodeValue
解决办法:统一用childNodes[i].firstChild.nodeValue方法访问节点元素值
17. 在形如
<root>
<en>text</en>
</root>
格式的XML,在IE中<en>是<root>的第一个子节点,可通过root.childNodes[0]或root.firstChild访问,但在FireFox中<en>是<root>的第二个子节点,第一个子元素是换行符,NodeType是#text;如果将XML换成如下格式
<root><en>text</en></root>
在IE和FireFox中<en>都是<root>的第一个子节点
18. 在用JS创建单选按钮上的方法上,IE与其它浏览器不同,要写出通用的创建方法就需要一种浏览器嗅探机制(browser-sniffing);IE是唯一能够识别uniqueID这一document对象专属属性的浏览器,故可用该属性区分浏览器类型;代码如下:
if(document.uniqueID){
//Internet Explorer
var radioButtion = document.createElement("<input type='radio' name='radioButtion' value ='checked'>");
}else{
//Standards Compliant
var readioButtion = document.createElement("input");
readioButtion.setAttribute("type","radio");
readioButtion.setAttribute("name","radioButtion");
readioButtion.setAttribute("value","checked");
}
19. 删除select列表标签的列表项应该用obj.remove(i);而不是用obj.options.remove(i);
20. 添加select列表标签的列表项应该用
var oOption = document.createElement('option');
oOption.text = text;
oOption.value = value;
targetArea.options[targetArea.options.length]= oOption; //new Option(text,value);
而不是用
var oOption = document.createElement('option');
oOption.text = text;
oOption.value = value;
targetArea.options.add(oOption);
21. IE中一般这样初始化一个XMLDOM对象
var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
FireFox不支持该方法(具体原因参见四.JS的语法兼容性.6.),兼容性代码如下
if (window.ActiveXObject){
var xmlDom = new ActiveXObject("Microsoft.XMLDOM");
}else{
if (document.implementation && document.implementation.createDocument){