您的位置:

JS addeventlistener第三个参数详解

一、捕获与冒泡模式

在讨论addEventListener第三个参数之前,先来了解一下事件流,也就是事件的传播方式。

事件流分为两种:捕获模式和冒泡模式。在捕获模式中,事件从最外层的节点开始传播,一直传递到最底层的节点;而冒泡模式则恰好相反,从最底层的节点开始传播,逐渐向外传递,到最后传递到最外层的节点。

浏览器对事件流的处理分为三个阶段:

1. 捕获阶段
2. 目标阶段
3. 冒泡阶段

捕获阶段是从document对象到触发事件的最外层元素,目标阶段是事件传播到目标元素,冒泡阶段是从目标元素到最外层元素。

在addEventListener中,第三个参数就是用来指定事件模式的,默认值为false,表示使用冒泡模式。如果将其设置为true,则表示使用捕获模式。

// 冒泡模式
document.getElementById('example').addEventListener('click', function() {
  console.log('我是来自 example 的点击事件!');
});

// 捕获模式
document.getElementById('example').addEventListener('click', function() {
  console.log('我是来自 example 的点击事件!');
}, true);

二、事件委托

事件委托是指利用事件机制,将一个父元素的事件处理程序注册到子元素中,使得子元素在触发事件时,可以执行父元素的事件处理程序。

这种编程方式的好处在于,可以减少事件程序的数量,提高页面性能,并且可以方便地动态添加或删除子元素,而不需要重新绑定事件处理程序。

实现事件委托的关键在于,可以通过事件传播机制,将子元素的事件传递到父元素上。在这个过程中,可以通过第三个参数来控制事件的传播方式。

以ul元素为父元素,li元素为子元素为例:

// 普通方式注册事件处理程序
var lis = document.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
  lis[i].addEventListener('click', function() {
    console.log('我是来自' + this.innerText + '的点击事件!');
  });
}

// 事件委托方式注册事件处理程序
document.querySelector('ul').addEventListener('click', function(event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    console.log('我是来自' + event.target.innerText + '的点击事件!');
  }
});

可以看到,事件委托可以减少事件处理程序的数量,也可以方便地动态添加或删除子元素。

三、事件绑定与解绑

addEventListener除了可以进行事件注册外,也可以通过removeEventListener方法来进行解绑。removeEventListener需要传入相同的事件类型、回调函数以及可选的useCapture参数,才能解绑之前相同的listener。

var triggerBtn = document.getElementById('trigger');

function clickEvent() {
  console.log('按钮被点击了!');
}

// 绑定事件处理程序
triggerBtn.addEventListener('click', clickEvent);

// 解绑事件处理程序
triggerBtn.removeEventListener('click', clickEvent);

四、一次性事件绑定

有时候我们需要在某个事件触发后,执行完事件处理程序后,解除事件绑定。由于removeEventListener需要了解之前绑定的listener函数,所以无法实现一次性解绑。不过可以借助匿名函数实现一次性事件绑定。

// 绑定事件处理程序
document.getElementById('example').addEventListener('click', function() {
  console.log('我是一次性的事件处理程序!');
  document.getElementById('example').removeEventListener('click', arguments.callee);
});

在回调函数内部使用arguments.callee,指向了该函数本身,从而达到了一次性的效果。

五、多次事件触发的节流和防抖

事件节流和防抖都是为了解决事件频繁触发而导致性能问题的问题,事件节流和防抖的本质是一样的,都是通过降低事件触发频率,从而提升性能。

5.1 节流

事件节流的本质是使用setTimeout,实现“定时触发”。它的实现方式是,第一次触发事件立即执行事件处理程序,然后在一定时间内不管事件触发了多少次,都不再执行事件处理程序,直到时间到了之后,才再次执行事件处理程序。

function throttle(fn, delay) {
  let timer = null;
  return function() {
    let args = arguments;
    let that = this;
    if (!timer) {
      timer = setTimeout(function() {
        fn.apply(that, args);
        timer = null;
      }, delay);
    }
  };
}

// 用法
document.getElementById('example').addEventListener('click', throttle(function() {
  console.log('我是通过节流方式处理的点击事件!');
}, 1000));

5.2 防抖

事件防抖的本质是使用setTimeout,实现“延迟触发”。它的实现方式是,事件触发后,等待一定时间,如果在这段时间内没有再次触发事件,就执行事件处理程序,否则,重新开始计时。

function debounce(fn, delay) {
  let timer = null;
  return function() {
    let args = arguments;
    let that = this;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function() {
      fn.apply(that, args);
      timer = null;
    }, delay);
  };
}

// 用法
document.getElementById('example').addEventListener('click', debounce(function() {
  console.log('我是通过防抖方式处理的点击事件!');
}, 1000));

六、总结

在日常的开发工作中,我们经常需要为元素添加各种事件处理程序,而利用addEventListener提供的第三个参数,可以实现捕获和冒泡模式的控制、事件委托、事件绑定和解绑、一次性事件绑定、事件节流和防抖等功能,实现更灵活、高效的事件管理。

JS addeventlistener第三个参数详解

2023-05-23
htmljs编程笔记(html代码笔记)

本文目录一览: 1、html代码和JS代码有什么区别 2、如何在html中调用js函数 3、JavaScript学习笔记之数组基本操作示例 4、HTML5初学者笔记 5、《web前端笔记7》js字符—

2023-12-08
js高级程序设计笔记14(js高级程序设计笔记14页)

本文目录一览: 1、JavaScript高级程序设计 该怎么看 2、JavaScript学习笔记之数组基本操作示例 3、JS中有关sort以及return的问题 JavaScript高级程序设计 该怎

2023-12-08
java学习笔记(java初学笔记)

2022-11-14
java第九天笔记,java第九章

2022-11-20
python笔记第六天,python第六周笔记

2022-11-21
重学java笔记,java笔记总结

2022-11-23
java方法整理笔记(java总结)

2022-11-08
php第三节笔记,php读书笔记

2022-12-02
python笔记第九章,python第八章

2022-11-20
印象笔记记录java学习(Java成长笔记)

2022-11-12
js解析各大视频代码(视频解析js脚本)

本文目录一览: 1、怎么查寻网页上视频的源代码 2、js如何解析url 3、高手,用javascript代码调用一个本地视频,让这个视频在网页中全屏播放,如何写代码啊 4、求一个js代码,有一个视频文

2023-12-08
python基础学习整理笔记,Python课堂笔记

2022-11-21
javascript简要笔记,JavaScript读书笔记

2022-11-17
java基础知识学习笔记一,Java基础笔记

2022-11-21
java笔记,大学java笔记

2022-11-28
数据库的笔记mysql,数据库管理系统笔记

2022-11-24
java笔记,尚硅谷java笔记

2022-12-01
js待办事项列表添加删除代码的简单介绍

本文目录一览: 1、“点击此处可添加笔记”的代码怎么写 2、js动态添加、删除html代码 3、vivo手机便签怎么一起删 “点击此处可添加笔记”的代码怎么写 输入符号就可以了第一步打开手机,点击备忘

2023-12-08
js事件中change,js事件中监听其他事件

本文目录一览: 1、js中的change事件不起作用 2、js中关于change的问题 3、这段JS代码为什么change事件中先删除上一次事件创建的option删不干净,会剩下一个城市 4、汇总js

2023-12-08