2

js基本操作-事件兼容性


写在前面

在WEB开发过程中,我们会经常的遇到各种事件监听以及事件处理的情况。

下面举个栗子说明下哈:

事件(Event)即为用户的动作,例如:用户点击鼠标,产生onclick事件;按下键盘,产生onkeyDown事件;改变输入框的值,产生onchange事件...

W3C标准规定,事件是作为函数的参数传入的,例如:

<p id="demo">
    <a>点击我将获得节点1</a>
    <a>点击我将获得节点2</a>
</p>
<script type="text/javascript">
document.getElementById("demo").onclick=function(e)
{
    alert(e.target);
}
</script>

当在元素上点击时,弹出警告框,内容为点击我将获得节点。这里函数传入的参数e,就是事件。浏览器会实时的根据用户点击的a标签的不同返回不同的节点内容。

这种做法在FireFox、Chrome、Safari等遵循W3C规范的浏览器下是没有问题的,唯独在IE(暂时仅限于8.0以下版本)下是行不通的,IE采用了一种非标准的方式,并不是将事件作为函数参数传入,而是将事件作为window对象的event属性:window.event传递进去的;而且,IE使用的是event.srcEvent来获取目标事件...

既然IE8以下不行,那有什么方法解决这个问题尼?
上面其实涉及到JS事件的兼容性问题,下面我们将从事件处理的角度来慢慢的分析这个问题。


当然,还是老话,所有的方法都来自网上,学到了才是自己的!!

然后,写在前面,带上我们可爱的小伙伴。废话不多说,下面我们开始看起吧!
小伙伴

基本介绍

文章主要是对js的this进行简单的说明和介绍,顺带会添加一些代码,没办法,语言能力有限,说明不了的只能直接上代码了。

IE浏览器从IE9开始已经支持DOM2事件处理程序,但是对于老版本的ie浏览器,任然使用attachEvent方式来为dom元素添加事件。值得庆幸的是微软已宣布2016年将不再对ie8进行维护,对于广大前端开发者无疑是一个福音。然而在曙光来临之前,仍然需要对那些不支持DOM2级事件处理程序的浏览器进行兼容性处理。
嘛,下面,将慢慢的处理事件在常规情况下(额,就是W3C和IE)的处理方式。

通用的事件侦听器函数实现

借鉴GitHub上markyun写的事件侦听器函数实现。下面我只是做一些注释性说明

// event(事件)工具集,来源:https://github.com/markyun
markyun.Event = {
    // 页面加载完成后
    // 主要是原生JS,页面只能加载一次window.onload;这里使用该方法可以绑定多个方法。
    readyEvent : function(fn) {
        if (fn==null) {
            fn=document;
        }
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = fn;
        } else {
            window.onload = function() {
                oldonload();
                fn();
            };
        }
    },
    // 视能力分别使用dom0||dom2||IE方式 来绑定事件
    // 下面的顺序:标准dom2,IE dom2, dom
    // 参数: 操作的元素,事件名称 ,事件处理程序
    addEvent : function(element, type, handler) {
        if (element.addEventListener) {
            //事件类型、需要执行的函数、是否捕捉
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, function() {
                handler.call(element);
            });
        } else {
            element['on' + type] = handler;
        }
    },
    // 移除事件
    removeEvent : function(element, type, handler) {
        if (element.removeEnentListener) {
            element.removeEnentListener(type, handler, false);
        } else if (element.datachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    }, 
    // 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
    stopPropagation : function(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation();// 标准w3c
        } else {
            ev.cancelBubble = true;// IE
        }
    },
    // 取消事件的默认行为
    preventDefault : function(event) {
        if (event.preventDefault) {
            event.preventDefault();// 标准w3c
        } else {
            event.returnValue = false;// IE
        }
    },
    // 获取事件目标
    getTarget : function(event) {
        // 标准W3C 和 IE
        return event.target || event.srcElement;
    },
    // 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
    getEvent : function(e) {
        var ev = e || window.event;
        if (!ev) {
            var c = this.getEvent.caller;
            while (c) {
                ev = c.arguments[0];
                if (ev && Event == ev.constructor) {
                    break;
                }
                c = c.caller;
            }
        }
        return ev;
    }
}; 

1.简单的说明

  • IE下的事件特例

IE下的事件对象是在window下的,而标准应该作为一个参数, 传为函数第一个参数;
IE的事件对象定义的属性跟标准的不同,如:

cancelBubble 默认为false, 如果为true就是取消事件冒泡;
returnValue 默认是true,如果为false就取消默认事件;
srcElement, 这个指的是标准W3C下的获取事件目标target,Firefox下的也是srcElement;

其他说明

  • 以上的所有方法,都来自网上。

  • 所有的方法,都必须脚踏实地,在具体应用场景下去分析、去选择,我们应该按照具体的情况,来选择方法。

  • 因为浏览器的多样性,前端的应用场景经常很复杂,性能优化充满挑战,也充满机遇。

  • 学会了才是自己的,知道会用会写,才是我们最终的目标。

参考文档


fania
63 声望3 粉丝