合成事件
合成事件是浏览器原生事件的跨浏览器的包装器,他拥有浏览器的所有原生事件相同接口,与原生事件不同,是react建造的事件,他的接口不会直接映射到原生事件的接口上(eg:onMouseLeave映射到mouseout),在 React 中,e.nativeEvent 才是原生 DOM 事件的那个 event。
事件委托
- 利用事件冒泡机制,将一个元素的响应事件放到另一个元素上(eg: <li>上的点击事件不用每个都是用onClick,直接放到<ul>上即可)
- 事件流响应机制为:事件捕获阶段 => 目标元素阶段 => 事件冒泡阶段,参见下图 image.png
- dom2级事件规定捕获阶段不会涉及事件目标,但是在ie9,safari,chrome,firefox和opera9.5及更高版本都会在捕获阶段触发事件对象上的事件,即:有两次机会出发事件操作(另一个发生的机会是在目标元素阶段)
合成事件影响案例
需要做一个弹窗打开/关闭 的功能,当点击 button 的时候打开,此时打开的情况下,点击弹窗区域外,就需要关闭。
// 直接在 button 上注册一个点击事件,同时在 document.body 注册一个点击事件,然后在 弹窗container 里阻止冒泡
class FuckEvent extends React.PureComponent {
state = {
showBox: false
}
componentDidMount() {
document.body.addEventListener('click', this.handleClickBody, false)
}
componentWillUnmount() {
document.body.removeEventListener('click', this.handleClickBody, false)
}
handleClickBody = () => {
this.setState({
showBox: false
})
}
handleClickButton = () => {
this.setState({
showBox: true
})
}
render() {
return (
<div>
<button onClick={this.handleClickButton}>点击我显示弹窗</button>
{this.state.showBox && (
<div onClick={e => e.stopPropagation()}>我是弹窗</div>
)}
</div>
)
}
}
实际结果为当前的阻止冒泡不生效,点击弹窗依然会被关闭
React 合成事件与原生事件执行顺序图
image.pngimage.png
- 合成事件执行需要冒泡到document后才会进行触发(16版本及以下),此时在捕获阶段,原生事件已经执行了,所以上述例子中点击弹窗也会直接关闭
- react中的阻止事件冒泡只能阻止合成事件的冒泡,无法处理原生事件
- 原生事件阻止冒泡可以阻止合成事件冒泡,因为走不到那一步了(17版本及以上,其实调用的就是绑定在当前节点的原生浏览器事件)
image.pngreact 16及之前的版本,事件监听是挂载到document节点上的,17及以上就挂载到dom容器上(root element)
参考文献:
网友评论