事件捕获与冒泡机制

433 阅读1分钟

2. 事件的捕获和冒泡机制你了解多少?

2.1 基本概念:

  • 捕获:自顶向下
  • 冒泡:自底向上

2.2 window.addEventListener()监听的是什么阶段的事件?

  • 参数:
    1. event:所有HTML DOM事件
    2. function:回调函数,事件对象会作为第一个参数传入回调函数
    3. useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行。
      • true:handler在捕获阶段执行
      • false:默认,handler在冒泡阶段执行

2.3 平常有哪些场景遇见了这种机制?

事件委托

  • 不使用冒泡机制的代码:

    const liList = document.getElementsByTagName('li');
    for (let i = 0; i < liList.length; i++) {
      liList[i].addEventListener('click', function (e) {
        alert(`内容为${e.target.innerHTML},索引为${i}`);
      })
    }
    

    需要在每一个子元素li上添加事件监听。

  • 使用冒泡机制的代码(事件委托):

    const ul = document.querySelector('ul');
    ul.addEventListener('click', function (e) {
      const target = e.target;
      if (target.tagName.toLowerCase() === 'li') {
        const liList = this.querySelectorAll('li');
        const index = Array.prototype.indexOf.call(liList, target);
        alert(`内容为${target.innerHTML},索引为${index}`);
      }
    })
    

2.4 情景模拟:

一个历史页面,上面有若干个按钮的点击逻辑,每个按钮都有自己的click事件。现在有个新需求:给每个访问的用户添加一个banned属性,当banned === true时,此用户点击页面上的任何按钮或元素,都不可响应原来的函数,而是直接alert提示:“你被封禁了”。

window.addEventListener('click', (e) => {
  if (banned) {
    e.stopPropagation();
    alert("你被封禁了");
  }
}, true);