js中的事件捕获和事件冒泡,以及由事件冒泡引入的事件委托

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38102188/article/details/84381960
  • 事件模型
    首先我们认识一下事件模型:
    在这里插入图片描述
    上图转自:https://zhuanlan.zhihu.com/p/26536815
    由上图所示,事件模型分为三个阶段:

  • 捕获阶段

  • 目标阶段

  • 冒泡阶段
    在IE8及其以前,IE浏览器监听事件的API为attachEvent, 但是它只能在事件冒泡阶段对事件进行捕获,而且在IE8以后的IE9等浏览器中已经弃用,所以这里我们不对它进行讨论。
    从IE9开始,实现事件监听的方法就统一使用符合W3C标准的addEventListener,一般来说,这个方法有三个参数。
    target.addEventListener(type, listener[, useCapture]);
    参数1:type,表示监听的事件类型的字符串,如"click"等。
    参数2:listener,一般来说,对应的是回调函数。事件触发时,会产生一个事件通知对象(一个实现了Event接口的对象),listener负责接收这个事件通知对象。
    参数3:useCapture,可选,true表示在捕获阶段接收到事件,false表示在冒泡阶段接收到事件。如果不指定的话,则默认为false,即在冒泡阶段接收到事件。
    但是,随着时间的推移,需求的增加,显然3个参数已经越来越不满足需求了,于是参数3正在慢慢演化成一个包含多个属性的对象,目前最常见的有以下3个属性:

  • capture
    依然表示是在事件捕获阶段接收事件(true)还是在冒泡阶段接收事件(false)。这里要注意的是,目前的addEventListener方法实际可以接收4个参数,该参数中的capture属性和原参数3useCapture的功能相同并且可以同时设置,遵循先注册的事件先捕获的原则(测试浏览器:Chrome68.0.3440.106)。

  • once
    这个属性是一个比较实用的属性,设置为true时可以控制listener最多被调用一次,默认为false。

  • passive
    表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。
    当然目前并不是所有的浏览器都支持第三个参数是对象的格式,更多细节可以参考:option支持的安全检测

  • 事件委托
    简单来讲,事件委托就是将一个元素的事件响应委托给另一个元素。一般来讲,我们会把一个元素或者一组元素的事项相应委托给它的父元素。
    如一个无序列表有很多列表项,我们需要在点击每一个列表项的时候添加相同的事件响应,那么我们就可以将该响应事件定义到它们的父元素ul上,这样在点击列表项li时,click事件通过冒泡到达父元素ul上,从而进行统一响应。
    采用事件委托有以下几个优点:

  • 减少内存消耗
    要知道,为每一个li元素添加事件响应函数是非常消耗内存的。

  • 动态绑定(删除)事件
    动态添加和删除li元素时,不用为新添加的元素单独绑定事件,或者为新删除的元素单独删除事件。

  • 减少代码量
    第三个好处是最最重要的了,用事件委托可以减少多少代码量啊!

猜你喜欢

转载自blog.csdn.net/m0_38102188/article/details/84381960
今日推荐