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