本文汇总了 JavaScript 在 IE 与 Firefox 等浏览器中常见的 DOM 操作、事件处理及属性访问差异。涵盖表单元素获取、自定义属性读取、事件对象兼容、窗口打开方式及表格操作等 23 个典型场景,提供统一代码写法以解决跨浏览器兼容问题。
JavaScript 多浏览器兼容性问题及解决方案
CSS 多浏览器兼容性问题及解决方案
一、document.formName.item(”itemName”) 问题
表单元素与集合类对象获取
问题说明:在 IE 环境下,可以通过 document.formName.item("itemName") 或 document.formName.elements["elementName"] 获取表单元素;而在 Firefox 中,仅支持 document.formName.elements["elementName"]。
解决方法:统一采用 document.formName.elements["elementName"] 来获取表单元素。
二、集合类对象问题
问题说明:在 IE 中,可以使用圆括号 () 或方括号 [] 获取集合类对象;但在 Firefox 中,只能使用方括号 [] 获取集合类对象。
解决方法:统一使用方括号 [] 来获取集合类对象。
三、自定义属性问题
自定义属性与 ID 获取差异
问题说明:在 IE 中,可以通过常规属性访问方法获取自定义属性,也可以使用 getAttribute() 方法;但在 Firefox 中,只能使用 getAttribute() 方法获取自定义属性。
解决方法:统一通过 getAttribute() 方法获取自定义属性。
四、eval(”idName”)问题
问题说明:在 IE 中,可以使用 eval("idName") 或 getElementById("idName") 来获取 ID 为 idName 的 HTML 对象;而在 Firefox 中,只能使用 getElementById("idName")。
解决方法:统一使用 getElementById("idName") 来获取 ID 为 idName 的 HTML 对象。
五、变量名与某HTML对象ID相同的问题
变量名与 HTML 对象 ID 冲突
问题说明:在 IE 中,HTML 对象的 ID 可以直接作为 document 的下属对象变量名使用;但在 Firefox 中则不行。此外,Firefox 允许使用与 HTML 对象 ID 相同的变量名,而 IE 不允许。
解决方法:使用 document.getElementById("idName") 替代 document.idName。建议避免使用与 HTML 对象 ID 相同的变量名以减少错误;在声明变量时,一律加上 var 关键字,以避免歧义。
六、const问题
常量定义与 Input 类型属性
问题说明:在 Firefox 中,可以使用 const 关键字或 var 关键字来定义常量;但在 IE 中,只能使用 var 关键字来定义常量。
解决方法:统一使用 var 关键字来定义常量。
七、input.type属性问题
问题说明:在 IE 中,input.type 属性为只读;但在 Firefox 中,input.type 属性为读写。
解决办法:不要直接修改 input.type 属性。如果必须修改,可以先隐藏原来的 input 元素,然后在相同位置插入一个新的 input 元素。
八、window.event问题
事件对象兼容处理
问题说明:window.event 只能在 IE 下运行,不能在 Firefox 下运行,这是因为 Firefox 的 event 对象只能在事件发生的现场使用。
解决方法:在事件发生的函数上加上 event 参数,在函数体内(假设形参为 evt)使用 var myEvent = evt ? evt : (window.event ? window.event : null)。
示例:
<input type="button" onclick="doSomething(event)"/>
<script language="javascript">
function doSomething(evt) {
var myEvent = evt ? evt : (window.event ? window.event : null)
...
}
九、event.x与event.y问题
事件坐标与源元素获取
问题说明:在 IE 中,event 对象有 x、y 属性,但没有 pageX、pageY 属性;而在 Firefox 中,event 对象有 pageX、pageY 属性,但没有 x、y 属性。
解决方法:var myX = event.x ? event.x : event.pageX; var myY = event.y ? event.y : event.pageY;
如果考虑第 8 条问题,就改用 myEvent 代替 event 即可。
十、event.srcElement问题
问题说明:在 IE 中,event 对象有 srcElement 属性,但没有 target 属性;而在 Firefox 中,event 对象有 target 属性,但没有 srcElement 属性。
解决方法:使用 srcObj = event.srcElement ? event.srcElement : event.target;
如果考虑第 8 条问题,就改用 myEvent 代替 event 即可。
十一、window.location.href问题
页面跳转与窗口打开方式
问题说明:在 IE 或 Firefox 2.0.x 下,可以使用 window.location 或 window.location.href;但在 Firefox 1.5.x 下,只能使用 window.location。
解决方法:使用 window.location 来代替 window.location.href。当然也可以考虑使用 location.replace() 方法。
十二、模态和非模态窗口问题
问题说明:在 IE 中,可以通过 showModalDialog 和 showModelessDialog 打开模态和非模态窗口;但在 Firefox 中则不能。
解决方法:直接使用 window.open(pageURL, name, parameters) 方式打开新窗口。
如果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用 window.opener 来访问父窗口。如果需要父窗口控制子窗口,使用 var subWindow = window.open(pageURL, name, parameters); 来获得新开的窗口对象。
十三、frame和iframe问题
Frame 对象访问与内容切换
以下面的 frame 为例:
(1)访问 frame 对象
IE:使用 window.frameId 或者 window.frameName 来访问这个 frame 对象;
Firefox:使用 window.frameName 来访问这个 frame 对象;
解决方法:统一使用 window.document.getElementById("frameId") 来访问这个 frame 对象;
(2)切换 frame 内容
在 IE 和 Firefox 中都可以使用 window.document.getElementById("frameId").src = "webjx.com.html" 或 window.frameName.location = "webjx.com.html" 来切换 frame 的内容;
如果需要将 frame 中的参数传回父窗口,可以在 frame 中使用 parent 关键字来访问父窗口。
十四、body载入问题
Body 载入时机与事件委托
问题说明:Firefox 的 body 对象在 body 标签没有被浏览器完全读入之前就存在;而 IE 的 body 对象则必须在 body 标签被浏览器完全读入之后才存在。
[注] 这个问题尚未实际验证,待验证后再来修改。
[注] 经验证,IE6、Opera9 以及 FireFox2 中不存在上述问题,单纯的 JS 脚本可以访问在脚本之前已经载入的所有对象和元素,即使这个元素还没有载入完成。
十五、事件委托方法
问题说明:在 IE 中,使用 document.body.onload = inject; 其中 function inject() 在这之前已被实现;在 Firefox 中,使用 document.body.onload = inject();
解决方法:统一使用 document.body.onload=new Function('inject()'); 或者 document.body.onload = function(){/* 这里是代码 */}
[注意] Function 和 function 的区别
十六、访问的父元素的区别
父节点访问与文本属性
问题说明:在 IE 中,使用 obj.parentElement 或 obj.parentNode 访问 obj 的父结点;在 Firefox 中,使用 obj.parentNode 访问 obj 的父结点。
解决方法:因为 Firefox 与 IE 都支持 DOM,因此统一使用 obj.parentNode 来访问 obj 的父结点。
十七、innerText的问题.
问题说明:innerText 在 IE 中能正常工作,但是 innerText 在 Firefox 中却不行。
解决方法:在非 IE 浏览器中使用 textContent 代替 innerText。
示例:
if(navigator.appName.indexOf("Explorer") >-1){
document.getElementById('element').innerText = "my text";
} else{
document.getElementById('element').textContent = ";my text";
}
[注] innerHTML 同时被 ie、firefox 等浏览器支持,其他的,如 outerHTML 等只被 ie 支持,最好不用。
十八、Table操作问题
Table 操作与样式赋值
问题说明:ie、firefox 以及其它浏览器对于 table 标签的操作都各不相同,在 ie 中不允许对 table 和 tr 的 innerHTML 赋值,使用 js 增加一个 tr 时,使用 appendChild 方法也不管用。document.appendChild 在往表里插入行时 FIREFOX 支持,IE 不支持
解决办法:把行插入到 TBODY 中,不要直接插入到表
解决方法:
//向table追加一个空行:
var row = otable.insertRow(-1);
var cell = document.createElement("td");
cell.innerHTML = "";
cell.className = "XXXX";
row.appendChild(cell);
[注] 建议使用 JS 框架集来操作 table,如 JQuery。
十九、对象宽高赋值问题
问题说明:Firefox 中类似 obj.style.height = imgObj.height 的语句无效。
解决方法:统一使用 obj.style.height = imgObj.height + ‘px';
二十、setAttribute('style','color:red;')
FIREFOX 支持(除了 IE,现在所有浏览器都支持),IE 不支持
解决办法:不用 setAttribute('style','color:red')
而用 object.style.cssText = ‘color:red;'(这写法也有例外)
最好的办法是上面种方法都用上,万无一失
二一、类名设置
类名设置与事件绑定
setAttribute('class','styleClass')
FIREFOX 支持,IE 不支持(指定属性名为 class,IE 不会设置元素的 class 属性,相反只使用 setAttribute 时 IE 自动识 CLASSNAME 属性)
解决办法:
setAttribute('class','styleClass')
setAttribute('className','styleClass')
或者直接 object.className='styleClass';
IE 和 FF 都支持 object.className。
二二、用setAttribute设置事件
var obj = document.getElementById('objId');
obj.setAttribute('onclick','funcitonname();');
FIREFOX 支持,IE 不支持
解决办法:
IE 中必须用点记法来引用所需的事件处理程序,并且要用赋予匿名函数
如下:
var obj = document.getElementById('objId');
obj.onclick=function(){fucntionname();};
这种方法所有浏览器都支持
二三、建立单选钮
动态创建单选按钮
IE 以外的浏览器
var rdo = document.createElement('input');
rdo.setAttribute('type','radio');
rdo.setAttribute('name','radiobtn');
rdo.setAttribute('value','checked');
IE:
var rdo =document.createElement(”<input name=”radiobtn” type=”radio” value=”checked” />”);
解决办法:
这一点区别和前面的都不一样。这次完全不同,所以找不到共同的办法来解决,那么只有 IF-ELSE 了
万幸的是,IE 可以识别出 document 的 uniqueID 属性,别的浏览器都不可以识别出这一属性。问题解决。