在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() 方法,則當前元素剩下的監聽函數將不會被執行。