在React中,咱们能够在建立element
的时候,传入事件和处理函数,这些事件会被作为合成事件
来处理,固然,有些时候,咱们也须要定义原生事件,好比给document
绑定事件。有些状况下,就须要经过阻止事件冒泡来实现预期的交互效果。下面是几个简单的demojavascript
好比有以下的代码:java
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时,控制台输出结果:react
inner div outer div
这两个事件都是合成事件,在点击时,两个事件会依次冒泡到document
,由统一的事件监听器处理。若是但愿阻止onClickOuter
触发,能够在onClickInner
内调用e.stopPropagation()
。须要注意的是,这里的e
是合成事件实例,调用stopPropagation
也只能阻止合成事件的冒泡。函数
假如咱们将onClickOuter
经过原生事件来绑定:this
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
, 控制台输出:code
outer div inner div
这是由于onClickInner
合成事件被触发的时候,说明点击事件已经经过冒泡传递到了document
,在这个过程当中,便会通过外层的div,进而触发该原生事件。这也说明了,合成事件的stopPropagation
只能阻止合成事件的冒泡。即便咱们在这里经过e.nativeEvent
获取到原生事件并调用stopPropagation
,也无济于事,由于上面已经说了,在该合成事件被触发的时候,已经冒泡到了document.
那么咱们该经过什么方式来阻止原生事件onClickOuter
被触发呢:
既然在onClickInner
处理不了,只能在onClickOuter
内处理了:component
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事件会依据绑定顺序的前后依次执行,因此控制台会输出:ip
inner div document
若是但愿阻止后绑定的事件触发,能够在onClickInner
内调用stopImmediatePropagation
:element
若是有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。若是其中某个监听函数执行了 event.stopImmediatePropagation() 方法,则当前元素剩下的监听函数将不会被执行。