其他分享
首页 > 其他分享> > DOM – Event Listener (bubble, capture, passive)

DOM – Event Listener (bubble, capture, passive)

作者:互联网

前言

老掉牙的东西, 主要是想写 passive, 随便也写一点 bubble 和 capture 吧.

 

Bubble

Dom 监听事件是会冒泡的. 什么意思 ?

上图有 2 个 box, parent box 嵌套 child box. 假设 parent 和 child 都有事件监听.

const parentBox = document.querySelector(".parent-box")!;
const childBox = document.querySelector(".child-box")!;
parentBox.addEventListener('click', () => console.log('clicked'));
childBox.addEventListener('click', () => console.log('clicked'));

请问, 我现在点击 child box. parent box 的事件会触发吗? 

答案是会的. 因为事件会冒泡 (注: 它的意思不是你点击了 child 同时也点击了 parent 哦, 只是点击了 child, 然后 child 事件触发, 然后冒泡到了 parent)

冒泡可以被阻止. 哪个 child 被点击了也可以被判断出来

parentBox.addEventListener("click", (event) => {
  console.log(event.currentTarget); // the listening element : parent
  console.log(event.target); // the clicked element : could be child or parent
});

childBox.addEventListener("click", (event) => {
  event.stopPropagation(); // 阻止冒泡
  event.stopImmediatePropagation(); // 顺便讲一下这个, 它除了 stopPropagation 外, 当前 element 后续的 listener 也不会触发
});

假设 child stopPropagation 那么 parent 就不会触发了.

 

Capture

首先事件触发的顺序是下面这样的

3 层 element. 其实是最外面开始触发的. 但是我们平常感觉好像只有 3,4,5 没有 1, 2 丫.

要触发 1, 2 就需要用到 capture 了.

上面 bubble 的例子多一层 grandparent

监听

const grandparentBox = document.querySelector(".grandparent-box")!;
const parentBox = document.querySelector(".parent-box")!;
const childBox = document.querySelector(".child-box")!;
grandparentBox.addEventListener("click", () => {
  console.log(5);
});
parentBox.addEventListener("click", () => {
  console.log(4);
});
childBox.addEventListener("click", () => {
  console.log(3);
});
parentBox.addEventListener(
  "click",
  () => {
    console.log(2);
  },
  { capture: true }
);
grandparentBox.addEventListener(
  "click",
  () => {
    console.log(1);
  },
  { capture: true }
);

我可以把监听的顺序倒过来写. 最终 console.log 顺序依然是 1 2 3 4 5. 其原理就是上面画的图, 事件触发是从最外面开始的, 只是我们一般上不适用 capture 所以以为只有 3,4,5 里到外.

stopPropagation

grandparentBox.addEventListener(
  "click",
  (e) => {
    console.log(1);
    e.stopPropagation();
  },
  { capture: true }
);

假如我在最外面 capture 就 stopPropagation 那么后续的 2,3,4,5 都不会触发了. 所以它的名字不叫 stopBubble. 因为 1,2 是 parent to child 并不是冒泡. 但是 stopPropagation 是一样可以阻止 "进入" 内层的.

使用场景

我好像只有在监听 document scroll 的时候会用到 capture.

 

标签:box,capture,console,log,parent,DOM,Listener,child,click
来源: https://www.cnblogs.com/keatkeat/p/16428841.html