這是 react 事件機制的第一篇,主要內容有:表象理解,驗證,意義和思考。前端
先回顧下 對react 事件機制基本理解,react 自身實現了一套本身的事件機制,包括事件註冊、事件的合成、事件冒泡、事件派發等,雖然和原生的是兩碼事,但也是基於瀏覽器的事件機制下完成的。react
咱們都知道react 的全部事件並無綁定到具體的 dom節點上而是綁定在了document 上,而後由統一的事件處理程序來處理,同時也是基於瀏覽器的事件機制(冒泡),全部節點的事件都會在 document 上觸發。chrome
上面是基於對 react 事件的一個基本的認知,那這個認知是否正確呢?咱們能夠經過簡單的方法進行驗證。瀏覽器
驗證內容:dom
爲了方便,直接經過 cli 建立一個項目。函數
代碼以下:性能
componentDidMount(){ document.getElementById('btn-reactandnative').addEventListener('click', (e) => { console.log('原生+react 事件: 原生事件執行'); }); } handleNativeAndReact = (e) => { console.log('原生+react 事件: 當前執行react事件'); } handleClick=(e)=>{ console.log('button click'); } render(){ return <div className="pageIndex"><p>react event!!!</p <button id="btn-confirm" onClick={this.handleClick}>react 事件</button> <button id="btn-reactandnative" onClick={this.handleNativeAndReact}>原生 + react 事件</button> </div> }
代碼中給兩個 button綁定了合成事件,單獨給btn#btn-reactandnative綁定了一個原生的事件。this
而後看下chrome 的控制檯,查看元素上的註冊事件。spa
通過簡單的驗證,能夠看到全部的事件根據不一樣的事件類型都綁定在了 document 上。觸發函數統一是 dispatchEvent。code
若是一個節點上同時綁定了合成和原生事件,那麼禁止冒泡後執行關係是怎樣的呢?
其實讀到這裏答案已經有了。咱們如今基於目前的知識去分析下這個關係。
由於合成事件的觸發是基於瀏覽器的事件機制來實現的,經過冒泡機制冒泡到最頂層元素,而後再由dispatchEvent統一去處理。
下面是我得出的結論:
原生事件阻止冒泡確定會阻止合成事件的觸發。
合成事件的阻止冒泡不會影響原生事件。
爲何呢?先回憶下瀏覽器事件機制
瀏覽器事件的執行須要通過三個階段,捕獲階段-目標元素階段-冒泡階段。
節點上的原生事件的執行是在目標階段,然而合成事件的執行是在冒泡階段,因此原生事件會先合成事件執行,而後再往父節點冒泡。
既然原生都阻止冒泡了,那合成還執行個啥嘞。
好,輪到合成的被阻止冒泡了,那原生會執行嗎?
固然會了。
由於原生的事件先於合成的執行,因此合成事件內阻止的只是合成的事件冒泡。(代碼我就不貼了)
因此得出結論:
原生事件(阻止冒泡)會阻止合成事件的執行
合成事件(阻止冒泡)不會阻止原生事件的執行
二者最好不要混合使用,避免出現一些奇怪的問題
react 本身作這麼多的意義是什麼?
個人理解的是
1.減小內存消耗,提高性能,不須要註冊那麼多的事件了,一種事件類型只在 document 上註冊一次
2.統一規範,解決 ie 事件兼容問題,簡化事件邏輯
3.對開發者友好
既然 react 幫咱們作了這麼多事兒,那他的背後的機制是什麼樣的呢?
事件怎麼註冊的,事件怎麼觸發的,冒泡機制怎樣實現的呢?
請看後續文章.....
更多精彩內容歡迎關注個人公衆號-前端張大胖