JS的事件绑定及相关兼容性问题

输入框
• 阅读 2363

面试中常会问到的一个问题,事件委托,我觉得除了能够看你对dom2事件的了解程度外,对浏览器的兼容也是有一定考察的。

考察到的点主要在addEventListener(),attachEvent(),事件对象等。
常见的考察方式是问你如何在一个列表中,点击某个li,就弹出被点击li的索引,或者让你实现类似JQuery的on和off这两个方法

简单来做,就可以给所有的li添加dom0级的事件,每个li都绑定一个onclick事件:

window.onload = function(){
    //dom0级的方式,直接为每个li绑定事件
    var ul = document.getElementById("ul");
    var lis = ul.querySelectorAll('li');
    for(var i = 0;i < lis.length;i++){
        (function(j){
            lis[j].onclick = function(e){
                alert(j+1);
            }
        })(i);
    }
}

这种方式很简单,但缺点也很明显,其实可以利用事件冒泡,把事件绑定在li的父级ul上,在点击之后,就会被ul的事件处理程序捕获到,从而处理。
这里要注意的就是兼容问题了,addEventListener并不被IE9以下的浏览器支持,与之对应的是attachEvent方法。而且,事件对象在标准和IE浏览器中也有不同。

window.onload = function(){
    var ul = document.getElementById("ul");
    if(ul.addEventListener){
        ul.addEventListener("click",handler);
    }else if(ul.attachEvent){
        ul.attachEvent("onclick",handler);
    }

    function handler(e){
        var ul = document.getElementById("ul");
        var e = e || window.event;                //事件对象兼容
        var liList = ul.getElementsByTagName("li");
        for(var i = 0;i<liList.length;i++){
            var target = e.target || e.srcElement;//事件对象属性的不同
            if(target == liList[i]){
                alert(i+1);
            }
        }
    }
}

上面的代码中就判断了浏览器支持的情况,从而去适配标准浏览器和IE浏览器。

如果是然你实现类似JQuery的on方法和off方法,可以参考下面啊的代码,这里统一参考js高程中的写法,定义一个EventUtil对象,来放这些方法。

var EventUtil = {
    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;
        }
    }
}

基本到这里也就完成了事件的绑定和解绑的方法。不过上面也说到了,这里其实最主要的也在兼容性的处理上,就不得不提一下事件对象了,dom和IE中的事件对象还是有很大不同的。
常用的几个如preventDefault(),stopPropagation(),target等,IE下均有不同的表示。见下

功能标准浏览器相关属性IE相关属性
事件的目标targetsrcElement
取消事件默认行为preventDefault()returnValue
取消事件冒泡stopPropagation()cancelBubble

剩下的就是利用这几个属性,扩展一下EventUtil对象,来做兼容了。

var EventUtil = {
    getEvent : function(event){
        return event ? event : window.event;
    },
    getTarget : function(event){
        return event.target || event.srcElement;
    },
    preventDefault : function(event){
        if(event.preventDefault){
            event.preventDefault();
        }else{
            event.returnValue = false;
        }
    },
    stopPropagation : function(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
}

点赞
收藏
评论区
推荐文章
马丁路德 马丁路德
4年前
对 JavaScript 中事件循环的理解​
一、是什么JavaScript在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事为什么要这么设计,跟JavaScript的应用场景有关JavaScript初期作为一门浏览器脚本语言,通常用于操作DOM,如果是多线程,一个线程进行了删除DOM,另一个添加DOM,此时浏览器该如何处理?为了解决单
Dax Dax
3年前
jQuery 的事件绑定和事件委托(事件代理)
简单以jQuery的on()方法为例说明:API:1.on(events,selector,data,handler) 如果on()方法的selector参数为空,事件处理程序就被称为直接绑定。每当在被绑定元素上(如下例中被绑定的document元素,译者注)发生事件时,无论这个事件发生在这个元素上还是从内层元素经冒泡而
Python进阶者 Python进阶者
3年前
一文解读JavaScript事件对象和表单对象
前言相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScript,因为它对做网页方面是有很大作用的。1.事件对象(Event)1).事件对象常量bubbles事件是否是起泡事件类型cancelabl
Wesley13 Wesley13
3年前
C#委托和事件
0\.前言事件和委托是C中的高级特性,也是C中很有意思的一部分。出现事件的地方,必然有委托出现;而委托则不一定会有事件出现。那为什么会出现这样的关系呢?这就需要从事件和委托的定义出发,了解其中的内在。1\.委托说起委托,就不得不回忆一下之前在Linq篇中介绍的匿名方法,其中提到了Func和Action这两个类型
Stella981 Stella981
3年前
QTreeWidget的Item点击事件
转载:cw123458945(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fblog.csdn.net%2Fcw123458945%2Farticle%2Fdetails%2F8160295)1!/usr/bin/envpython23i
Wesley13 Wesley13
3年前
Java面试官最爱的volatile关键字
在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度,而以volatile关键字作为一个小的切入点,往往可以一问到底,把Java内存模型(JMM),Java并发编程的一些特性都牵扯出来,深入地话还可以考察JVM底层实现以及操作系统的相关知识。下面我们以一次假想的面试过程,来深入了解下volitile关键字吧!面试官:
Wesley13 Wesley13
3年前
JS的事件冒泡和事件捕获
什么是事件?事件是文档和浏览器窗口中发生的特定的交互瞬间。事件是javascript应用跳动的心脏,也是把所有东西黏在一起的胶水,当我们与浏览器中web页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击,鼠标经过某个特定元素或按下键盘上的某些按键,事件还可能是web浏览器中发生的事情,比如说某
Wesley13 Wesley13
3年前
Java面试官最常问的volatile关键字
在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯出来,再深入的话还会考察JVM底层实现以及操作系统的相关知识。接下来让我们在一个假想的面试过程中来学习一下volitile关键字吧。1\.Java并发
Easter79 Easter79
3年前
Spring事件机制之ApplicationListener与ApplicationEvent 一、一些概念 二、spring事件机制
一、一些概念 事件是可以被控件识别的操作,如按下确定按钮,选择某个单选按钮或者复选框。每一种控件有自己可以识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事,等等。事件有系统事件和用户事件。系统事件由系统激发,如时间每隔24小时,银行储户的存款日期增加一天。用户事件由用户激发,如用户点击按钮,在文本框中显示特定的文
Stella981 Stella981
3年前
JavaScript 基础(四)
HTMLDOMEvent(事件)HTML4.0的新特性之一是有能力使HTML事件触发浏览器中的动作(action),比如当用户点击某个HTML元素时启动一段JavaScript。下面是一个属性列表,这些属性可插入HTML标签来定义事件动作。onclick//当用户点
Stella981 Stella981
3年前
JavaScript事件 ——常见事件
1.什么是事件?      当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是Web浏览器中发生的事情,比如说某个Web页面加载完成,或者是用户滚动窗口或改变窗口大小。常见事件:(http://www.runoo