深入React事件系統(React點擊空白部分隱藏彈出層;React阻止事件冒泡失效)

來源:互聯網
上載者:User

標籤:通過   簡化   with   element   tac   overflow   系統   iat   http   

只關注括弧內問題的同學,可直接跳轉到藍字部分。(標題起的有點大,其實只討論一個問題)

兩個在React組件上綁定的事件,產生衝突後,使用e.stopPropagation(),阻止冒泡,即可防止事件衝突,毫無問題。

今天是踩了個React事件的坑,需求可以簡化為:點擊框體以外的部分則隱藏框體。最直接的想法,document上綁定個事件,設定控制顯示隱藏的state為false,在框體上綁定個事件,阻止冒泡。這樣點擊框體內部就不會觸發document上的事件。

等寫完了,發現一個問題,無法阻止冒泡,一搜尋,好傢夥,好多人問e.stopPropagation()為什麼無法阻止事件冒泡,但是鮮有靠譜的回答。我第一個想法是原生事件和React事件產生衝突。明顯綁定原生事件是不符合React精神的,但我決定在探索真理的路上走下去了。

為了直觀的調試,把需求轉化為,點擊框體內 alert(1)點擊框體外 alert(2)。

在document上綁定 alert(2),框體上(框體為React組件,下同)綁定 alert(1),不做特殊處理,點擊框體內,根據事件冒泡,先彈 1 再彈 2 。這一點符合預期。此時e.stopPropagation()無法阻止冒泡。

經過 Stack Overflow 解惑 e.nativeEvent.stopImmediatePropagation() 可以完美實現預期。

下面進入探索環節,經查閱資料,得出以下結論:

  1. React為了提高效率,把事件都委託給了document,所以 e.stopPropagation() 並非是不能阻止冒泡,而是等他阻止冒泡的時侯,事件已經傳遞給document了,沒東西可阻止了。可以通過在document.body上綁定 alert(3),直觀的瞭解這一點,3 是優先於 1 彈出的。
  2. e.stopPropagation()不行,瀏覽器支援一個好東西,e.stopImmediatePropagation() 他不光阻止冒泡,還能阻止在當前事件觸發元素上,觸發其它事件。這樣即使你都綁定到document上也阻止不了我了吧。
  3. 這樣做還不行,React對原生事件封裝,提供了很多好東西,但也省略了某些特性。e.stopImmediatePropagation() 就是被省略的部分,然而,他給了開口:e.nativeEvent ,從原生的事件對象裡找到stopImmediatePropagation(),完活。

測試代碼如下:

class Test extends React.Component{    componentDidMount(){        document.onclick=this.two;    }    one(e){        e.nativeEvent.stopImmediatePropagation();        alert(1)    }    two(){        alert(2)    }    render(){        return(<div style={{height:150,width:150,backgroundColor:"#000"}} onClick={this.one}/>)    }}ReactDOM.render(    <Test/>,    document.getElementById("test"));

感謝且不僅限於:

http://stackoverflow.com/questions/24415631/reactjs-syntheticevent-stoppropagation-only-works-with-react-events

http://wiki.jikexueyuan.com/project/react/event-system.html

https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation

深入React事件系統(React點擊空白部分隱藏彈出層;React阻止事件冒泡失效)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.