在React中,我们能够在建立element
的时刻,传入事宜和处置惩罚函数,这些事宜会被做为合成事宜
来处置惩罚,固然,有些时刻,我们也须要定义原生事宜,比方给document
绑定事宜。有些情况下,就须要经由过程阻挠事宜冒泡来完成预期的交互效果。下面是几个简朴的demo
Demo
比方有以下的代码:
import React from 'react'
class Demo1 extends React.Component{
onClickInner(e){
console.log('inner div')
}
onClickOuter(e){
console.log('outer div')
}
render(){
return <div onClick={this.onClickOuter}>
<div onClick={this.onClickInner}>inner div</div>
</div>
}
}
当我们点击 inner div时,控制台输出效果:
inner div
outer div
这两个事宜都是合成事宜,在点击时,两个事宜会顺次冒泡到document
,由一致的事宜监听器处置惩罚。如果愿望阻挠onClickOuter
触发,能够在onClickInner
内挪用e.stopPropagation()
。须要注重的是,这里的e
是合成事宜实例,挪用stopPropagation
也只能阻挠合成事宜的冒泡。
如果我们将onClickOuter
经由过程原生事宜来绑定:
class App extends React.Component {
onClickInner(e) {
e.stopPropagation();
console.log("inner div");
}
onClickOuter(e) {
console.log("outer div");
}
componentDidMount() {
this.outer.onclick = this.onClickOuter;// 经由过程DOM 0级绑定
}
render() {
return (
<div ref={ref => (this.outer = ref)}>
<div id='inner' onClick={this.onClickInner}>123</div>
</div>
);
}
}
虽然在onClickInner
内挪用了 e.stopPropagation
, 然则原生事宜照样会经由过程冒泡来触发,而且会先于onClickInner
, 控制台输出:
outer div
inner div
这是由于onClickInner
合成事宜被触发的时刻,申明点击事宜已经由过程冒泡通报到了document
,在这个过程当中,便会经由外层的div,进而触发该原生事宜。这也申清楚明了,合成事宜的stopPropagation
只能阻挠合成事宜的冒泡。纵然我们在这里经由过程e.nativeEvent
获取到原生事宜并挪用stopPropagation
,也杯水车薪,由于上面已说了,在该合成事宜被触发的时刻,已冒泡到了document.
那末我们该经由过程什么体式格局来阻挠原生事宜onClickOuter
被触发呢:
既然在onClickInner
处置惩罚不了,只能在onClickOuter
内处置惩罚了:
onClickOuter(e) {// 这里e是原生事宜
if(e.target && e.target.id === 'inner'){
return ;
}
console.log("outer div");
}
如果我们将原生事宜绑定在了document
上:
class App extends React.Component {
constructor(props) {
super(props);
// this.bindDocument();
}
onClickInner(e) {
console.log("inner div");
}
componentDidMount() {
this.bindDocument();
}
bindDocument() {
document.addEventListener("click", function(e) {
console.log("document");
});
}
render() {
return (
<div id="inner" onClick={this.onClickInner}>
123
</div>
);
}
}
上面代码中,在组件挂载终了后,再给document绑定click事宜,这时刻,React合成事宜已注册完成,当点击时,document上的click事宜会根据绑定递次的前后顺次实行,所以控制台会输出:
inner div
document
如果愿望阻挠后绑定的事宜触发,能够在onClickInner
内挪用stopImmediatePropagation
:
如果有多个雷同范例事宜的事宜监听函数绑定到同一个元素,当该范例的事宜触发时,它们会根据被增加的递次实行。如果个中某个监听函数实行了 event.stopImmediatePropagation() 要领,则当前元素剩下的监听函数将不会被实行。