This website requires JavaScript.

浏览器兼容,js hack

2018.08.07 11:30字数 8107阅读 133喜欢 0评论 0

添加事件/移除事件方法

// 添加事件方法  
addHandler: function (element, type, handler) {
    if (element.addEventListener) { //检测是否为DOM2级方法  
        element.addEventListener(type, handler, false);
    } else if (element.attachEvent) { //检测是否为IE级方法  
        element.attachEvent(‘on’ + type, handler);
    } else { //检测是否为DOM0级方法
        element[‘on’ + type] = handler;
    }
}

// 移除事件方法  
removeHandler: function (element, type, handler) {
    if (element.removeEventListener) { //检测是否为DOM2级方法  
        element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) { //检测是否为IE级方法  
        element.detachEvent(‘on’ + type, handler);
    } else { //检测是否为DOM0级方法
        element[‘on’ + type] = null;
    }
}

分别检验是否是DOM2级,IE、DOM0级。
DOM0级:将一个函数赋给一个事件处理程序属性。具有简单、跨浏览器的优势。添加的事件处理程序会在冒泡阶段执行。事件处理程序也是在它所依附的元素作用于中执行。
删除事件处理程序:将事件处理程序的属性的值设为null。
DOM2级:DOM2级事件处理方法:addEventListener()和removeEventListener(),这两种方法 接受三个参数,要处理的事件名,作为事件处理程序的函数和一个布尔值,布尔值为true时,表示在捕获阶段调用事件处理函数;布尔值为false,表示在冒泡阶段调用事件处理函数。
调用addEventListener()添加的事件处理程序只能通过removeEventListener()移除,移除时传入的参数和添加处理程序时使用的参数必须一致。所以通过addEventListener()添加的匿名函数无法移除。与DOM0级相同,事件处理程序也是在它所依附的元素作用于中执行。
大多数情况下将事件处理程序添加到事件流的冒泡阶段,可以最大限度的兼容各种浏览器。
IE事件处理程序:两个方法:attachEvent()和detachEvent()。接收两个参数:要处理的事件名,作为事件处理程序的函数。与上述两种情况的主要区别是作用域不同:attachEvent()和detachEvent()会在全局作用域中执行。
除了作用域的区别外,DOM2级和IE事件处理程序可以添加多个事件处理程序,而OM0级只能添加一个。

获取事件及事件对象目标

getEvent: function (event) {
    return event ? event : window.event;
}
getTarget: function (event) {
    return event.target || event.srcElement;
}

event:事件处理对象,包含与创建它的特定事件有关的属性和方法。其中target(事件的目标)是其中一个成员。
在兼容DOM的浏览器中,event对象只是简单的传入和返回。而IE中,event参数是为定义的,因此就会返回window.event。返回事件的目标,IE中为event.srcElemnt。

阻止浏览器默认事件及阻止冒泡的兼容性写法

preventDefault: function (event) {
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }
}

stopPropagation: function (event) {
    if (event.stopPropagation) {
        event.stopPropagationt();
    } else {
        event.cancelBubble = true;
    }
}

阻止浏览器默认事件:IE中为:event.returnValue=false
阻止事件冒泡:IE中为cancelBubble=true,因为IE中只有事件冒泡,所以只能取消事件冒泡。
stopPropagatation()既能阻止事件冒泡也能阻止事件捕获。

获取mouseover和mouseout事件相关元素信息

getRelatedTarget: function (event) {
    if (event.relateTarget) {
        return event.relateTarget;
    } else if (event.toElement) {
        return event.toElement;
    } else if (event.fromElement) {
        return event.fromElement;
    } else {
        return null;
    }
}

DOM 通过event对象的relatedTarget属性提供了相关元素的信息。这个属性只对mouseover和mouseout事件才包含值,对于其他事件,这个属性值为null。在mouseover事件触发时,IE的fromElement属性保存了相关元素,在mouseout事件触发时,IE的toElement属性保存了相关元素。

鼠标滚轮判断

getButton: function (event)
    if (document.implementation.hasFeature("MouseEvents","2.0")){
        return event.button;
    }
    else {
        switch (event.button) {
            case 0:
            case 1:
            case 3:
            case 5:
            case 7:
                return O;
            case 2:
            case 6:
                return 2;
            case 4:
                return 1;
        }
    }
}

对于mousedown和mouseup事件来说,则在其event对象存在一个button 属性,表示按下或释放的按钮。
DOM的button 属性可能有如下3个值: 0表示主鼠标按钮, 1表示中间的鼠标按钮(鼠标滚轮按钮) , 2表示次鼠标按钮。在常规的设置中,主鼠标按钮就是鼠标左键,而次鼠标按钮就是鼠标右键,IE8及之前版本也提供了button属性,但这个属性的值与DOM的button属性有很大差异。

0:表示没有按下按钮。
1:表示按下了主鼠标按钮。
2:表示按下了次鼠标按钮。
3:表示同时按下了主、次鼠标按钮。
4:表示按下了中间的鼠标按钮。
5:表示同时按下了主鼠标按钮和中间的鼠标按钮。
6:表示同时按下了次鼠标按钮和中间的鼠标按钮。
7:表示同时按下了三个鼠标按钮。

能够获取鼠标滚轮增量的方法

getWheelDelta: function (event) {
    if (event.wheelDelta) {
        return (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta);
    }
    else{
        return -event.detail * 40; //firefox中值为+3表示向上滚,-3表示向下滚
    }
}

该事件兼容性问题存在于:opera、Firefox和其他浏览器之间。

跨浏览器获得字符编码

getCharCode: function (event) {
    if (typeof event.charCode == "number"){
        return event.charCode;
    }
    else{
        return event.keyCode;
    }
}

IE9,Firefox,Chrome,Safari的event对象都支持charcode属性,在发生keypress事件时才包含值。值为按下那个键所对应的ASCII编码。IE8及之前版本和Opera则使用keyCode。

访问、设置剪切板中的数据

// 访问剪贴板中的数据
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);
    }
}

要访问剪切板中的数据,可以使用clipboardData对象:IE中,这个对象是window对象的属性;而在Firefox,Chrome,Safar中,这个对象是event对象的属性。

setAttribute('style','color:red;')

FIREFOX支持(除了IE,现在所有浏览器都支持),IE不支持

解决办法:不用setAttribute('style','color:red')

而用object.style.cssText = ‘color:red;'(这写法也有例外)

最好的办法是上面种方法都用上,万无一失。

类名设置
class属性在W3C DOM中扮演着很重要的角色,但由于浏览器差异性仍然存在。
使用setAttribute("class", vName)语句动态设置Element的class属性在firefox中是行的通的,在IE中却不行。
因为使用IE内核的浏览器不认识"class",要改用"className";同样,firefox 也不认识"className"。
所以常用的方法是二者兼备:

element.setAttribute("class", vName);
element.setAttribute("className", vName); //for IE

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” />”);

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操作问题
ie、firefox以及其它浏览器对于 table 标签的操作都各不相同,在ie中不允许对table和tr的innerHTML赋值,使用js增加一个tr时,使用appendChild方法也不管用document.appendChild在往表里插入行时FIREFOX支持,IE不支持。

访问的父元素的区别
问题说明:在IE下,使用 obj.parentElementobj.parentNode 访问obj的父结点;在firefox下,使用 obj.parentNode 访问obj的父结点。
解决方法:因为firefox与IE都支持DOM,因此统一使用obj.parentNode 来访问obj的父结点。

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;

document.formName.item(”itemName”) 问题
问题说明:
IE下,可以使用 document.formName.item(”itemName”)document.formName.elements ["elementName"]
Firefox 下,只能使用document.formName.elements["elementName"]
解决方法:统一使用document.formName.elements["elementName"]

自定义属性问题
问题说明:
IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用 getAttribute() 获取自定义属性;
Firefox下,只能使用 getAttribute() 获取自定义属性。
解决方法:统一通过 getAttribute() 获取自定义属性。

集合类对象问题
问题说明:
IE下,可以使用 () 或 [] 获取集合类对象;
Firefox下,只能使用 []获取集合类对象。
解决方法:统一使用 [] 获取集合类对象。

eval(”idName”)问题
问题说明:
IE下,可以使用 eval(”idName”) 或 getElementById(”idName”) 来取得 id 为 idName 的HTML对象;
Firefox下,只能使用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。
解决方法:统一用 getElementById(”idName”) 来取得 id 为 idName 的HTML对象。

const问题
问题说明:
IE下,只能使用var关键字来定义常量(IE11解决了)。
Firefox下,可以使用const关键字或var关键字来定义常量;
解决方法:统一使用var关键字来定义常量。

input.type属性问题
问题说明:
IE下 input.type 属性为只读;
但是Firefox下 input.type 属性为读写。
解决办法:不修改 input.type 属性。如果必须要修改,可以先隐藏原来的input,然后在同样的位置再插入一个新的input元素。

事件委托方法
问题说明:
IE下,使用 document.body.onload = inject; 其中function inject()在这之前已被实现;
在Firefox下,使用 document.body.onload = inject();
解决方法:统一使用 document.body.onload=new Function('inject()'); 或者 document.body.onload = function()

对象宽高赋值问题
问题说明:
FireFox中类似 obj.style.height = imgObj.height 的语句无效。
解决方法:统一使用 obj.style.height = imgObj.height + ‘px';

BASE ON NUXT + NODE + MONGODB BY OUYANG90