ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DOM – Event Listener (bubble, capture, passive)

2022-06-30 22:36:38  阅读:204  来源: 互联网

标签:box capture console log parent DOM Listener child click


前言

老掉牙的东西, 主要是想写 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有