理解:react中的事件都是合成事件牢硅,不是把每一個dom的事件綁定在dom上声诸,而是把事件統(tǒng)一綁定到document中,觸發(fā)時通過事件冒泡到document進行觸發(fā)合成事件围苫,因為是合成事件裤园,所以我們無法去使用e.stopPropagation去阻止撤师,而是使用e.preventDefault去阻止剂府。
1.事件注冊:組件更新或者裝載時,在給dom增加合成事件時剃盾,需要將增加的target傳入到document進行判斷腺占,給document注冊原生事件回調(diào)為dispatchEvent(統(tǒng)一的事件分發(fā)機制)淤袜。
2.事件存儲:EventPluginHub負責(zé)管理React合成事件的callback,它將callback存儲到listennerBank中,另外還存儲了負責(zé)合成事件的Plugin衰伯,Event存儲到listennerbank中铡羡,每一個元素在listennerBank中會有唯一的key。
3.事件觸發(fā)執(zhí)行:點擊時冒泡到docunment中意鲸,觸發(fā)注冊原生事件的回調(diào)dispatchEvent烦周,獲取到觸發(fā)這個事件的最深層元素,事件執(zhí)行利用react的批處理機制怎顾。
案例
<div onClick={this.parentClick} ref={ref => this.parent = ref}>
<div onClick={this.childClick} ref={ref => this.child = ref}>
test
</div>
</div>
點擊test后
1.首先獲取到this.child
2.遍歷此元素的所有父元素读慎,依次對每一級元素進行處理
3.構(gòu)成合成事件
4.將每一級的合成事件存儲在eventQueen事件隊列中
5.遍歷,是否組織冒泡槐雾,是則停止夭委,否則繼續(xù)
6.釋放已經(jīng)完成的事件
4.合成事件:循環(huán)所有類型的eventPlugin,對應(yīng)每個事件類型募强,生成不同的事件池株灸,如果是空,則生成新的擎值,有則用之前的慌烧,根據(jù)唯一key獲取到指定的回調(diào)函數(shù),再返回帶有參數(shù)的回調(diào)函數(shù)幅恋。
5.總流程:組件裝載/更新 -- 新增/刪除事件 -- eventplugin添加到ListennerBank中監(jiān)聽事件 -- 觸發(fā)事件 -- 生成合成事件 -- 通過唯一key獲取到指定函數(shù) -- 執(zhí)行指定回調(diào)函數(shù) -- 執(zhí)行完畢后釋放