摘要:本博客大概介紹一下的事件機制,并給出整體的設(shè)計圖,但不涉及底層的源碼結(jié)構(gòu)分析。整個設(shè)計圖以上是對的合成事件一個大概的介紹,里面還有很多細節(jié)和原理沒說到,有興趣的同學可以進一步研究一下源碼的細節(jié)。
好久沒寫博客了,前段時間太忙以至于平時的積累都記錄在內(nèi)網(wǎng)的wiki里,趁著這幾天有空,將這段時間所積累的干貨慢慢的分享出來,如果內(nèi)容有不正確的地方,歡迎糾正。
本博客大概介紹一下react的事件機制,并給出整體的設(shè)計圖,但不涉及react底層的源碼結(jié)構(gòu)分析。
現(xiàn)象:
demo1:nidemo2: render() { returnni}
雖然兩個例子都是通過標簽內(nèi)嵌的方式將click事件進行綁定,但其中的原理是不一樣的,demo1是采用原生的事件處理,demo2是采用react的合成事件機制處理;
合成事件:
對于jsx來說,是采用了類似于DOM0的事件綁定的方式進行處理,它會收到一個合成事件對象(synthicevent),該對象集成了原生事件對象的所有特性,而且還是事件冒泡機制,并且能支持stopPropagation和preventDefault兩種方法;
原生事件與合成事件的區(qū)別:
原生的事件綁定是采用小寫onclick,而react則是采用大寫onClick;
原生事件綁定的是一個js的字符串,而react采用的是一個函數(shù)的指針;
合成事件的實現(xiàn)機制:
事件機制原型圖:
該圖大概的表示了react的事件機制的整體結(jié)構(gòu)圖,接下來具體說說它里面的原理。
真正的監(jiān)聽者:
對于react來說,雖然事件是綁定在v-dom中,但其實真正的監(jiān)聽者只有一個,就是結(jié)構(gòu)中最外層的document對象進行監(jiān)聽,主要采用了事件冒泡的方式,將v-dom中觸發(fā)的事件包裝成一個合成事件,然后通過事件冒泡的方式,最終冒泡到最外層的document監(jiān)聽和執(zhí)行(就是事件委托);
事件注冊:
事件注冊是在組件生成的時候,將v-dom中所有的事件都對應(yīng)的原生事件都注冊在document的監(jiān)聽器中,例如onClick對應(yīng)的原生事件是onclick,如果v-dom中有綁定了onClick,那么就會將對應(yīng)的onclick事件注冊在document中,整個注冊過程可以三個階段:
1) 將v-dom中所涉及到的綁定事件所對應(yīng)的原生事件都在enqueuePutListener中綁定到document身上;
2) 將v-dom中所有事件的事件處理函數(shù)都存放在listenerBank中,存放的方式是以registrtionname和key作為索引存放,其中registrtionname是事件名,key是instance的id值,所以形式是:
listenerBank[registrtionname][key] = listener
這樣的好處是將可能要觸發(fā)的事件分門別類,以及將對應(yīng)的listener也分門別類存放;為了就是在事件觸發(fā)的時候,能從listenerBank中取出同類型的listener存放在dispatchListener中;
3) 最后將dispatchEvent作為callback函數(shù),放在addEventListener和removeEventListener里面,等待事件的觸發(fā);
合成事件:
當事件觸發(fā)的時候,不會直接將原生的事件發(fā)送到最外層的document中,而是經(jīng)過處理,將處理后的事件發(fā)送到document中;事件合成的經(jīng)過:獲取原生事件,并通過原生事件的類型和所在組件的id值,在listenerBank中取出對應(yīng)的listener函數(shù),并存放在_dispatchListener隊列中,然后將該實例存放到_dispatchInstance隊列中,這樣一來,可以將同類型的事件函數(shù)都按照順序存放在_dispatchListener中,最后一同處理;
事件發(fā)布:
當事件觸發(fā)時,會先原生事件變成合成事件,然后傳遞到document中,然后document會通過dispatchEvent回調(diào)函數(shù)依次執(zhí)行dispatchListener中同類型的事件監(jiān)聽函數(shù)。
整個設(shè)計圖:
以上是對react的合成事件一個大概的介紹,里面還有很多細節(jié)和原理沒說到,有興趣的同學可以進一步研究一下源碼的細節(jié)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100358.html
摘要:另外第三方也可以通過的事件插件機制來合成自定義事件,盡管很少人這么做。抽象跨平臺事件機制。打算干預(yù)事件的分發(fā)。事件是的一個自定義事件,旨在規(guī)范化表單元素的變動事件。 showImg(https://segmentfault.com/img/remote/1460000019961124?w=713&h=307); 當我們在組件上設(shè)置事件處理器時,React并不會在該DOM元素上直接綁定...
摘要:給注冊原生事件回調(diào)為統(tǒng)一的事件分發(fā)機制。根據(jù)元素唯一標識和事件類型從中取出回調(diào)函數(shù)返回帶有合成事件參數(shù)的回調(diào)函數(shù)總流程將上面的四個流程串聯(lián)起來??梢姡卣{(diào)函數(shù)是直接調(diào)用調(diào)用的,并沒有指定調(diào)用的組件,所以不進行手動綁定的情況下直接獲取到的是。 關(guān)于React事件的疑問 1.為什么要手動綁定this 2.React事件和原生事件有什么區(qū)別 3.React事件和原生事件的執(zhí)行順序,可以混...
摘要:前言這是事件機制的第一篇,主要內(nèi)容有表象理解,驗證,意義和思考。因為合成事件的觸發(fā)是基于瀏覽器的事件機制來實現(xiàn)的,通過冒泡機制冒泡到最頂層元素,然后再由統(tǒng)一去處理。合成事件的阻止冒泡不會影響原生事件。 showImg(https://segmentfault.com/img/bVbtvP2?w=800&h=420); 前言 這是 react 事件機制的第一篇,主要內(nèi)容有:表象理解,驗證...
摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因為Virtual DOM 在內(nèi)存中是以對象的形式存在的,所以React 基于 Virtual DOM 實現(xiàn)了...
摘要:事件簡介事件是合成事件,所有事件都自動綁定到最外層上。支持事件的冒泡機制,我們可以使用和來中斷它。這樣做簡化了事件處理和回收機制,效率也有很大提升。事件類型合成事件的事件類型是原生事件類型的一個子集。 React事件簡介 React事件是合成事件,所有事件都自動綁定到最外層上。因為Virtual DOM 在內(nèi)存中是以對象的形式存在的,所以React 基于 Virtual DOM 實現(xiàn)了...
摘要:注冊事件的回調(diào)函數(shù)由來統(tǒng)一管理,根據(jù)事件的類型和組件標識為唯一標識事件并進行存儲。利用中注入的例如會將原生的事件轉(zhuǎn)化成合成的事件,然后批量執(zhí)行存儲的回調(diào)函,回調(diào)函數(shù)的執(zhí)行分為兩步,第一步是將所有的合成事件放到事件隊列里面,第二步是逐個執(zhí)行。 最近在閱讀《深入React技術(shù)?!芬粫校l(fā)現(xiàn)了之前使用React中并沒有注意到的React事件與瀏覽器原生事件之間的區(qū)別,鑒于好久已經(jīng)沒有寫...
閱讀 2960·2019-08-30 15:55
閱讀 2075·2019-08-30 14:02
閱讀 1362·2019-08-29 15:23
閱讀 1070·2019-08-29 11:27
閱讀 537·2019-08-26 11:43
閱讀 3245·2019-08-26 10:32
閱讀 1300·2019-08-23 14:41
閱讀 3354·2019-08-23 14:41