# JS 中的浏览器兼容问题及其处理方式
# 1.宽高问题
var winW = document.body.clientWidth || document.docuemntElement.clientWidth; //网页可见区域宽
var winH = document.body.clientHeight || document.docuemntElement.clientHeight; //网页可见区域宽
//以上为不包括边框的宽高,如果是offsetWidth或者offsetHeight的话包括边框
var winWW = document.body.scrollWidth || document.docuemntElement.scrollWidth; //整个网页的宽
var winHH = document.body.scrollHeight || document.docuemntElement.scrollHeight; //整个网页的高
var scrollHeight =
document.body.scrollTop || document.docuemntElement.scrollTop; //网页被卷去的高
var scrollLeft =
document.body.scrollLeft || document.docuemntElement.scrollLeft; //网页左卷的距离
var screenH = window.screen.height; //屏幕分辨率的高
var screenW = window.screen.width; //屏幕分辨率的宽
var screenX = window.screenLeft; //浏览器窗口相对于屏幕的x坐标(除了FireFox)
var screenXX = window.screenX; //FireFox相对于屏幕的X坐标
var screenY = window.screenTop; //浏览器窗口相对于屏幕的y坐标(除了FireFox)
var screenYY = window.screenY; //FireFox相对于屏幕的y坐标
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.event 事件问题
1) 添加事件/移除事件方法
// 添加事件
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false)
}else if(element.attachEvent){
element.attachEvent("on"+type,handler)
}else{
element["on"+type]=handler
}
}
// 移除事件方法
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false)
}else if(element.detachEvent){
element.detachEvent("on"+type,handler)
}else{
element["on"+type]=null
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
分别检验是否是 DOM2 级,IE、DOM0 级。
DOM0级:将一个函数赋给一个事件处理程序属性。具有简单、跨浏览器的优势。添加的事件处理程序会在冒泡阶段执行。事件处理程序也是在它所依附的元素作用于中执行。删除事件处理程序:将事件处理程序的属性的值设为 null。DOM2级:DOM2 级事件处理方法:addEventListener()和removeEventListener(),这两种方法 接受三个参数,要处理的事件名,作为事件处理程序的函数和一个布尔值,布尔值为true时,表示在捕获阶段调用事件处理函数;布尔值为false,表示在冒泡阶段调用事件处理函数。 调用addEventListener()添加的事件处理程序只能通过removeEventListener()移除,移除时传入的参数和添加处理程序时使用的参数必须一致。所以通过addEventListener()添加的匿名函数无法移除。与 DOM0 级相同,事件处理程序也是在它所依附的元素作用于中执行。 大多数情况下将事件处理程序添加到事件流的冒泡阶段,可以最大限度的兼容各种浏览器。IE 事件处理程序:两个方法:
attachEvent()和detachEvent()。接收两个参数:要处理的事件名,作为事件处理程序的函数。与上述两种情况的主要区别是作用域不同:attachEvent()和detachEvent()会在全局作用域中执行。 除了作用域的区别外,DOM2级和IE事件处理程序可以添加多个事件处理程序,而OM0级只能添加一个。
2) 获取事件及事件对象目标
// 获取事件对象的兼容性写法
getEvent:function(event){
return event?event:window.event
}
getTarget:function(event){
return event.target||event.srcElement
}
// 获取事件对象目标的兼容性写法
2
3
4
5
6
7
8
event:事件处理对象,包含与创建它的特定事件有关的属性和方法。其中 target(事件的目标)是其中一个成员。
在兼容 DOM 的浏览器中,event 对象只是简单的传入和返回。而 IE 中,event 参数是为定义的,因此就会返回window.event。
返回事件的目标,IE 中为event.srcElemnt。
3) 阻止浏览器默认事件及阻止冒泡的兼容性写法
// 阻止浏览器默认事件兼容性写法
preventDefault: funcion(event){
var event=event||window.event;
if(event.preventDefault){
event.preventDafault()
}else{
// IE
event.returnValue=false
}
}
// 阻止冒泡的兼容性写法
stopPropagation:function(event){
var event=event||window.event;
if(event.stopPropagation){
// stopPropagatation()既能阻止事件冒泡也能阻止事件捕获
event.stopPropagation()
}else{
event.cancelBubble=true
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
4) 获取mouseover和mouseout事件相关元素信息
getRelatedTarget: function(event){
if (event.relatedTarget)
{
return event.relatedTarget;//标准下返回相关元素
}else if (event.toElement)
{
return event.toElement;//mouseout事件触发,保存相关元素
}else if (event.fromElement)
{
return event.fromElement;//mouseover事件触发,保存相关元素
}
}
2
3
4
5
6
7
8
9
10
11
12
DOM 通过event对象的relatedTarget属性提供了相关元素的信息。这个属性只对mouseover和mouseout事件才包含值,对于其他事件,这个属性值为 null。在mouseover事件触发时,IE 的fromElement属性保存了相关元素,在mouseout事件触发时,IE 的 toElement 属性保存了相关元素。
5) 跨浏览器获得字符编码
getCharCode:function(event){
if(typeof event.charCode=='number'){
return event.charCode
}else{
return event.keyCode
}
}
2
3
4
5
6
7
IE9,Firefox,Chrome,Safari 的 event 对象都支持 charcode 属性,在发生keypress事件时才包含值。值为按下那个键所对应的 ASCII 编码。IE8 及之前版本和 Opera 则使用 keyCode。
6) 访问、设置剪切板中的数据
// 访问剪切板中的数据
getClipboardText:function(event){
var clipboardData=(event.clipboardData||window.clipboardData)
return clipboardData.getData("text")
}
//设置剪切板中的数据
setClipboardText:function(event,value){
if(event.clipboardData){
return event.clipboardData.setData("text/plain",value)
}else if(window.clipboardData){
return window.clipboardData.setData("text",value)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
要访问剪切板中的数据,可以使用clipboardData对象:IE 中,这个对象是window对象的属性;而在 Firefox,Chrome,Safar 中,这个对象是event对象的属性
# 3.属性设置
// 该方法FIREFOX支持,IE不支持。
var obj = document.getElementById("objId");
obj.setAttribute("onclick", "funcitonname()");
// IE中必须用点记法来引用所需的事件处理程序,并且要用赋予匿名函数, 如下:
// 这种方法所有浏览器都支持。
var obj = document.getElementById("objId");
obj.onclick = function() {
fucntionname();
};
2
3
4
5
6
7
8
9
# 4.类名设置
class 属性在 W3C DOM 中扮演着很重要的角色,但由于浏览器差异性仍然存在。使用setAttribute("class", vName)语句动态设置 Element 的 class 属性在 firefox 中是行的通的,在 IE 中却不行。因为使用 IE 内核的浏览器不认识class,要改用className;
同样,firefox 也不认识className。所以常用的方法是二者兼备。
// IE和FF都支持object.className。
element.setAttribute("class", vName);
element.setAttribute("className", vName); //for IE
2
3
# 5.建立单选钮
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” />”);
2
3
4
5
6
7
# 6.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";
}
2
3
4
5
# 7.Table 操作问题
ie、firefox 以及其它浏览器对于 table 标签的操作都各不相同,在 ie 中不允许对table和tr的innerHTML赋值,使用 js 增加一个 tr 时,使用appendChild方法也不管用,document.appendChild在往表里插入行时 FIREFOX 支持,IE 不支持。
访问的父元素的区别:在IE下,使用 obj.parentElement或 obj.parentNode 访问 obj 的父结点;在 firefox 下,使用 obj.parentNode访问 obj 的父结点。
解决方法:因为 firefox 与 IE 都支持 DOM,因此统一使用obj.parentNode 来访问 obj 的父结点。
# 8.event.x 与 event.y 问题
问题说明:IE下,even 对象有x、y 属性,但是没有pageX、pageY 属性;Firefox下,even 对象有pageX、pageY 属性,但是没有x、y 属性。
解决方法:
var myX = event.x ? event.x : event.pageX;
var myY = event.y ? event.y : event.pageY;
2
# 9.document.formName.item(”itemName”) 问题
问题说明:IE下,可以使用 document.formName.item(”itemName”)或 document.formName.elements ["elementName"]; Firefox 下,只能使用document.formName.elements["elementName"]。
解决方法: 统一使用 document.formName.elements["elementName"]。
# 10.自定义属性问题
问题说明:IE 下,可以使用获取常规属性的方法来获取自定义属性,也可以使用 getAttribute() 获取自定义属性;Firefox 下,只能使用getAttribute() 获取自定义属性。
解决方法: 统一通过 getAttribute()获取自定义属性。
# 11.集合类对象问题
问题说明:IE 下,可以使用 () 或 [] 获取集合类对象;Firefox 下,只能使用 [ ]获取集合类对象。
解决方法: 统一使用 [] 获取集合类对象。
# 12.eval(”idName”)问题
问题说明:IE 下,可以使用 eval(”idName”)或 getElementById(”idName”) 来取得id 为 idName的 HTML 对象;Firefox 下,只能使用getElementById(”idName”) 来取得 id 为 idName 的 HTML 对象。
解决方法: 统一用 getElementById(”idName”)来取得 id 为 idName 的HTML对象。
# 13.const 问题
问题说明:Firefox 下,可以使用const关键字或var关键字来定义常量;IE 下,只能使用var关键字来定义常量(IE11 解决了)。
解决方法: 统一使用 var 关键字来定义常量。
# 14.input.type 属性问题
问题说明:IE 下input.type 属性为只读;但是 Firefox 下 input.type 属性为读写。
解决办法: 不修改 input.type 属性。如果必须要修改,可以先隐藏原来的input,然后在同样的位置再插入一个新的input元素。
# 15.事件委托方法
问题说明:IE 下,使用 document.body.onload = inject; 其中function inject()在这之前已被实现;在 Firefox 下,使用 document.body.onload = inject();
解决方法: 统一使用 document.body.onload=new Function('inject()'); 或者document.body.onload = function()
# 16.对象宽高赋值问题
问题说明:FireFox 中类似 obj.style.height = imgObj.height的语句无效。
解决方法: 统一使用obj.style.height = imgObj.height + ‘px';
[注] innerHTML 同时被 ie、firefox 等浏览器支持,其他的,如 outerHTML 等只被 ie 支持,最好不用。
# react 浏览器的兼容问题
默认情况下,生成的项目支持所有现代浏览器。 如果你的项目想支持 Internet Explorer 9 , 10 和 11 ,那么需要 polyfills,可自行百度安装使用。
# 检测对象中属性
你想使用 document.querySelector()来选择一个 id,并且让它能兼容 IE6 浏览器,但是在 IE6 浏览器中这个函数是不存在的,那么使用这个操作符来检测这个函数是否存在就显得非常的有用
//if in
if ("querySelector" in document) {
document.querySelector("#id");
} else {
document.getElementById("id");
}
2
3
4
5
6
# 参考
https://segmentfault.com/a/1190000015722419