DOM事件的顺序:捕获vs冒泡
事件的传播有两个阶段。这被称为“捕捉”和“冒泡”。
| | / \
---------------| |----------------- ---------------| |-----------------
| element1 | | | | element1 | | |
| -----------| |----------- | | -----------| |----------- |
| |element2 \ / | | | |element2 | | | |
| ------------------------- | | ------------------------- |
| Event CAPTURING | | Event BUBBLING |
----------------------------------- -----------------------------------
捕获阶段首先发生,然后是冒泡阶段。当您使用常规DOM api注册一个事件时,默认情况下,事件将是冒泡阶段的一部分,但这可以在事件创建时指定
// CAPTURING event
button.addEventListener('click', handleClick, true)
// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)
在React中,冒泡事件也是默认使用的。
// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>
// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>
让我们来看看我们的handleClick回调(React):
function handleClick(e) {
// This will prevent any synthetic events from firing after this one
e.stopPropagation()
}
function handleClick(e) {
// This will set e.defaultPrevented to true
// (for all synthetic events firing after this one)
e.preventDefault()
}
一个我在这里没有看到的替代方案
如果你在所有的事件中调用e.preventDefault(),你可以检查一个事件是否已经被处理,并防止它再次被处理:
handleEvent(e) {
if (e.defaultPrevented) return // Exits here if event has been handled
e.preventDefault()
// Perform whatever you need to here.
}
关于合成事件和本机事件的区别,请参阅React文档:https://reactjs.org/docs/events.html