logo

事件传递可视化

免费线上事件传递可视化工具。点嵌套盒子,看 DOM 事件沿 capture、target、bubble 三阶段流动,切换各层监听器,并看清 stopPropagation 把路径截在哪。
logo
啪唧开发工坊
事件传递可视化

事件传递可视化

免费线上事件传递可视化工具。点嵌套盒子,看 DOM 事件沿 capture、target、bubble 三阶段流动,切换各层监听器,并看清 stopPropagation 把路径截在哪。
处理中

关于事件传递

三个阶段

当你点击一个元素,事件不是只在那个元素上触发。它从树的顶端往下传到目标(capture 阶段),在目标本身触发(target 阶段),再往上传回顶端(bubble 阶段)。默认你加的监听器在 bubble 阶段执行,这就是为什么点子元素也会触发祖先的 handler。用 capture 模式加监听器,则会改在下行途中执行。

中断传递

在监听器里调用 stopPropagation,会让事件不再往下一层传递,剩下的层就不会被触发。它不会挡掉同一元素上的其他监听器——那是 stopImmediatePropagation 的工作。在上方选一个中断点,看触发顺序被截短。

常见问题

关于这个主题的常见疑问与实用解答。

capture 和 bubble 差在哪?

它们是同一趟旅程的两个方向。capture 由上而下,从最外层祖先往目标走,发生在抵达目标之前。bubble 由下而上,从目标往最外层祖先走。用一般方式加的监听器在 bubble 阶段执行;给 addEventListener 第三个参数传 true,就改在 capture 阶段执行。

为什么点子元素,父层的 handler 也会跑?

因为冒泡。事件在子元素(目标)上触发后,会往上传回每一层祖先,沿路执行各层的 bubble 阶段监听器。这常常有用——让容器上的一个 handler 就能回应任何子元素的点击——但会让以为事件只停在被点元素上的人意外。

什么时候该用 stopPropagation?

少用为妙,只在子元素要处理事件、且真的必须阻止祖先也反应时用——例如可点击卡片里的一颗按钮,不该同时触发卡片的点击。太常用它通常代表事件设计可以更简单;它也可能弄坏其他正当依赖事件传到共同祖先的代码。