精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

60行代碼實現React的事件系統

開發 項目管理
本文會用60行代碼實現這兩個模塊,讓你快速了解React事件系統的原理。

大家好,我卡頌。

由于如下原因,React的事件系統代碼量很大:

  • 需要抹平不同瀏覽器的差異
  • 與內部的「優先級機制」綁定
  • 需要考慮所有瀏覽器事件

但如果抽絲剝繭會發現,事件系統的核心只有兩個模塊:

  • SyntheticEvent(合成事件)
  • 模擬實現的事件傳播機制

本文會用60行代碼實現這兩個模塊,讓你快速了解React事件系統的原理。

在線DEMO地址[1]

Demo的效果

對于如下這段JSX:

const jsx = (
<section onClick={(e) => console.log("click section")}>
<h3>你好</h3>
<button
onClick={(e) => {
// e.stopPropagation();
console.log("click button");
}}
>
點擊
</button>
</section>
);

在瀏覽器中渲染:

const root = document.querySelector("#root");
ReactDOM.render(jsx, root);

點擊按鈕,會依次打印:

click button
click section

如果在button的點擊回調中增加e.stopPropagation(),點擊后會打印:

click button

我們的目標是將JSX中的onClick替換為ONCLICK,但是點擊后的效果不變。

也就是說,我們將基于React自制一套事件系統,他的事件名的書寫規則是形如「ONXXX」的全大寫形式。

實現SyntheticEvent

首先,我們來實現SyntheticEvent(合成事件)。

SyntheticEvent是瀏覽器原生事件對象的一層封裝。兼容所有瀏覽器,同時擁有和瀏覽器原生事件相同的API,如stopPropagation()和preventDefault()。

SyntheticEvent存在的目的是抹平瀏覽器間在事件對象間的差異,但是對于不支持某一事件的瀏覽器,SyntheticEvent并不會提供polyfill(因為這會顯著增大ReactDOM的體積)。

我們的實現很簡單:

class SyntheticEvent {
constructor(e) {
this.nativeEvent = e;
}
stopPropagation() {
this._stopPropagation = true;
if (this.nativeEvent.stopPropagation) {
this.nativeEvent.stopPropagation();
}
}
}

接收「原生事件對象」,返回一個包裝對象。原生事件對象會保存在nativeEvent屬性中。

同時,實現了stopPropagation方法。

實際的SyntheticEvent會包含更多屬性和方法,這里為了演示目的簡化了

實現事件傳播機制

事件傳播機制的實現步驟如下:

  1. 在根節點綁定事件類型對應的事件回調,所有子孫節點觸發該類事件最終都會委托給「根節點的事件回調」處理。
  2. 尋找觸發事件的DOM節點,找到其對應的FiberNode(即虛擬DOM節點)
  3. 收集從當前FiberNode到根FiberNode之間所有注冊的「該事件對應回調」
  4. 反向遍歷并執行一遍所有收集的回調(模擬捕獲階段的實現)
  5. 正向遍歷并執行一遍所有收集的回調(模擬冒泡階段的實現)

首先,實現第一步:

// 步驟1
const addEvent = (container, type) => {
container.addEventListener(type, (e) => {
// dispatchEvent是需要實現的“根節點的事件回調”
dispatchEvent(e, type.toUpperCase(), container);
});
};

在入口處注冊點擊回調:

const root = document.querySelector("#root");
ReactDOM.render(jsx, root);
// 增加如下代碼
addEvent(root, "click");

接下來實現「根節點的事件回調」:

const dispatchEvent = (e, type) => {
// 包裝合成事件
const se = new SyntheticEvent(e);
const ele = e.target;

// 比較hack的方法,通過DOM節點找到對應的FiberNode
let fiber;
for (let prop in ele) {
if (prop.toLowerCase().includes("fiber")) {
fiber = ele[prop];
}
}

// 第三步:收集路徑中“該事件的所有回調函數”
const paths = collectPaths(type, fiber);

// 第四步:捕獲階段的實現
triggerEventFlow(paths, type + "CAPTURE", se);

// 第五步:冒泡階段的實現
if (!se._stopPropagation) {
triggerEventFlow(paths.reverse(), type, se);
}
};

接下來收集路徑中「該事件的所有回調函數」。

收集路徑中的事件回調函數

實現的思路是:從當前FiberNode一直向上遍歷,直到根FiberNode。收集遍歷過程中的FiberNode.memoizedProps屬性內保存的「對應事件回調」:

const collectPaths = (type, begin) => {
const paths = [];

// 不是根FiberNode的話,就一直向上遍歷
while (begin.tag !== 3) {
const { memoizedProps, tag } = begin;

// 5代表DOM節點對應FiberNode
if (tag === 5) {
const eventName = ("on" + type).toUpperCase();

// 如果包含對應事件回調,保存在paths中
if (memoizedProps && Object.keys(memoizedProps).includes(eventName)) {
const pathNode = {};
pathNode[type.toUpperCase()] = memoizedProps[eventName];
paths.push(pathNode);
}
}
begin = begin.return;
}

return paths;
};

得到的paths結構類似如下:

捕獲階段的實現由于我們是從目標FiberNode向上遍歷,所以收集到的回調的順序是:

  • [目標事件回調, 某個祖先事件回調, 某個更久遠的祖先回調 ...]

要模擬捕獲階段的實現,需要從后向前遍歷數組并執行回調。

遍歷的方法如下:

const triggerEventFlow = (paths, type, se) => {
// 從后向前遍歷
for (let i = paths.length; i--; ) {
const pathNode = paths[i];
const callback = pathNode[type];

if (callback) {
// 存在回調函數,傳入合成事件,執行
callback.call(null, se);
}
if (se._stopPropagation) {
// 如果執行了se.stopPropagation(),取消接下來的遍歷
break;
}
}
};

注意,我們在SyntheticEvent中實現的stopPropagation方法,調用后會阻止遍歷的繼續。

冒泡階段的實現

有了捕獲階段的實現經驗,冒泡階段很容易實現,只需將paths反向后再遍歷一遍就行。

總結React事件系統的核心包括兩部分:

  • SyntheticEvent
  • 事件傳播機制

事件傳播機制由5個步驟實現。

總的來說,就是這么簡單。

參考資料

[1]在線DEMO地址:

https://codesandbox.io/s/optimistic-torvalds-9ufc5?file=/src/index.js

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2019-07-25 08:20:37

代碼開發神經網絡

2021-12-16 06:21:16

React組件前端

2022-04-15 08:07:21

ReactDiff算法

2023-07-03 07:51:47

2017-03-28 21:03:35

代碼React.js

2019-11-15 15:50:41

JS代碼React前端

2014-05-26 10:07:18

Javascript俄羅斯方塊

2023-02-20 09:45:32

技術AI

2021-12-26 12:10:21

React組件前端

2024-03-01 13:49:00

數據訓練

2021-04-27 11:28:21

React.t事件元素

2023-07-06 20:40:57

圣誕抽抽樂H5

2018-01-23 09:17:22

Python人臉識別

2020-12-17 08:06:33

CSS 日歷界面

2022-03-26 22:28:06

加密通信Python

2022-04-09 09:11:33

Python

2022-06-16 10:33:14

代碼AI

2024-02-04 17:16:22

ReactVue前端

2024-03-20 09:31:00

圖片懶加載性能優化React

2015-02-09 10:43:00

JavaScript
點贊
收藏

51CTO技術棧公眾號

色综合天天综合狠狠| 精品一区二区三区中文字幕老牛| 国产精品电影一区二区| 国产日韩在线亚洲字幕中文| 又嫩又硬又黄又爽的视频| 久久99国产精品二区高清软件| 国产精品入口麻豆九色| 91精品国产综合久久久久久蜜臀| 黄色a级片在线观看| 中文字幕区一区二区三| 欧美视频二区36p| 91视频网页| 91久久国产视频| 九一精品国产| 欧美日韩国产美女| 美女av免费观看| www.中文字幕| 亚洲人metart人体| 呦呦在线视频| 日本欧美在线观看| 99国产精品99久久久久久粉嫩| 欧美中文字幕一区二区三区亚洲| 视频一区视频二区视频三区高| 在线观看黄色网| 欧美在线高清| 亚洲午夜精品视频| 中文字幕avav| 欧美亚洲韩国| 亚洲卡通欧美制服中文| 国产传媒欧美日韩| 免费观看一区二区三区毛片| 欧美呦呦网站| 欧美精品一区二区三区高清aⅴ| 熟女人妇 成熟妇女系列视频| 成人性生交大片免费看午夜 | 97香蕉碰碰人妻国产欧美| 91tv亚洲精品香蕉国产一区| 亚洲精品视频在线观看免费| 国内精品国语自产拍在线观看| 欧美成人一区二区视频| 亚洲大胆视频| 久久久久www| 久久精品国产亚洲av久| 久久综合偷偷噜噜噜色| 欧美性黄网官网| 国产激情片在线观看| 成人性爱视频在线观看| 97精品超碰一区二区三区| 成人激情在线观看| 日本中文字幕在线观看视频| 在线成人www免费观看视频| 日韩精品视频在线观看免费| 日韩av网站电影| 欧美这里只有精品| 在线观看麻豆| 97久久人人超碰| 亚洲自拍偷拍福利| 一级日韩一级欧美| 蜜臀av性久久久久av蜜臀妖精| 欧美激情三级免费| 国产高潮流白浆| 欧美hd在线| 亚洲天堂日韩电影| xxxx黄色片| 国产精东传媒成人av电影| 日韩欧美一级二级三级久久久| 日韩av片免费观看| 色黄视频在线观看| 天天影视网天天综合色在线播放 | 国产91色在线观看| 欧洲成人一区| 欧美三级电影一区| 午夜免费精品视频| 91精品美女| 欧美日韩国产高清一区| 天天视频天天爽| 色8久久影院午夜场| 91福利国产成人精品照片| 国产一区亚洲二区三区| 天天免费亚洲黑人免费| 欧美伊人久久大香线蕉综合69| 亚洲色欲久久久综合网东京热| 毛片大全在线观看| 亚洲成人免费视频| 91成人在线观看喷潮教学| 欧美a级在线观看| 精品日本美女福利在线观看| 亚洲不卡中文字幕无码| 伊人222成人综合网| 有坂深雪av一区二区精品| 国产中文字幕乱人伦在线观看| а√天堂资源官网在线资源| 日韩欧美在线播放| 色99之美女主播在线视频| 欧美激情专区| 丰满人妻av一区二区三区| 成人h版在线观看| 蜜桃视频免费观看一区| 久久亚洲国产成人| 欧美日韩激情在线观看| 亚洲激情精品| 国产91在线播放九色快色| 久久久久久久久久久久久av| 三级影片在线观看欧美日韩一区二区| 国产精品久久久久福利| jlzzjlzzjlzz亚洲人| 国产大片一区二区| 久久久久久久久四区三区| 国产三级在线观看| 亚洲色欲色欲www| 九九爱精品视频| 最新日韩一区| 精品少妇一区二区三区视频免付费 | 亚洲精品午夜国产va久久成人| 亚洲欧美日本国产专区一区| 日本韩国欧美精品大片卡二| 91成人一区二区三区| 岛国精品一区二区| 日韩欧美国产二区| 2020国产在线视频| 日本福利一区二区| 一级黄色免费毛片| heyzo久久| 欧美激情精品久久久久久黑人 | 中文字幕乱码视频| 成人国产精品免费观看动漫| 日韩在线国产| av资源网在线播放| 777午夜精品免费视频| 少妇精品一区二区三区| 亚洲在线久久| 国产精品高清免费在线观看| 国产小视频一区| 国产精品久久久久久久久久久免费看 | 国产精品igao激情视频| xxxxx.日韩| 日韩精品免费在线视频| 九九免费精品视频| 蜜臀av亚洲一区中文字幕| 精品午夜一区二区| av毛片在线看| 欧美理论电影在线| 丁香激情五月少妇| 国产亚洲毛片在线| 91免费在线观看网站| 欧美69xxxx| 欧美性猛交xxxx免费看| 日本在线不卡一区二区| 欧美一区二区三区高清视频| 青草青草久热精品视频在线网站| 午夜精品久久久久久久99老熟妇| 中文字幕在线播放不卡一区| 国产日韩一区二区在线观看| 亚洲91网站| 久久精品国产一区二区三区| 伊人22222| 91色|porny| 你懂的av在线| 久久男人av| 久久人人爽人人爽人人片av高请 | 91女人视频在线观看| 日韩精品久久一区二区| 久久久久久久久久久久电影| 精品国偷自产在线| 国产又粗又猛又爽又黄视频| 国产精品久久久久影院亚瑟 | 国产91一区二区三区| а√资源新版在线天堂| 欧美一区二区三区精品| 日本视频在线免费| 蜜桃久久久久久久| 杨幂一区欧美专区| av在线精品| 不卡中文字幕av| 亚洲av无码一区二区三区dv | 男人与禽猛交狂配| 国产美女娇喘av呻吟久久| 中文字幕精品在线播放| 精品久久国产一区| 欧美精品久久久久久久免费观看| 亚洲AV无码一区二区三区少妇| 亚洲成a人片综合在线| 亚洲婷婷在线观看| 亚洲一区二区三区四区五区午夜 | 日韩精品极品在线观看| 日韩欧美在线观看免费| 99久久国产综合精品麻豆| 日韩精品资源| 欧美精品高清| 麻豆国产va免费精品高清在线| 精品人妻伦一区二区三区久久| 亚洲老妇xxxxxx| 亚洲天堂av网站| 久久久蜜桃一区二区人| 伊人久久婷婷色综合98网| 香蕉成人app| 2019中文字幕免费视频| 国产高清免费av在线| 欧美人狂配大交3d怪物一区 | 亚洲欧美激情一区二区| 日韩Av无码精品| 香蕉精品999视频一区二区| 日韩电影大全在线观看| 久久国产精品免费一区二区三区| 高清欧美性猛交xxxx黑人猛交| 精品成人一区二区三区免费视频| 欧美日韩中字一区| 一区二区三区福利视频| 国产精品高清亚洲| 亚洲婷婷在线观看| 久久精品99久久久| 国产日韩一区二区在线观看| 久久久久久久久丰满| 欧美不卡在线一区二区三区| 国产日本亚洲| 国产精品91久久久久久| 麻豆tv入口在线看| 亚洲第一天堂av| 中文字幕在线视频第一页| 午夜精品福利一区二区三区蜜桃| 9.1片黄在线观看| av亚洲精华国产精华| 拔插拔插华人永久免费| 99国产精品| 日韩精品一区二区三区电影| 九九在线高清精品视频| 99久久99久久精品国产片| 国产国产一区| 97婷婷大伊香蕉精品视频| 国产在线高清理伦片a| 日韩精品中文字幕视频在线| 精品人妻伦一区二区三区久久| 色狠狠色噜噜噜综合网| 91香蕉在线视频| 亚洲视频你懂的| 国产麻豆a毛片| 久久久综合激的五月天| 少妇伦子伦精品无吗| 久久99精品久久久久久| 伊人影院综合在线| 日韩中文字幕亚洲一区二区va在线 | 一区二区三区日| 色诱亚洲精品久久久久久| 国产污视频在线看| 一区二区三区四区乱视频| 国内偷拍精品视频| 亚洲欧美在线高清| 成年人在线免费看片| 欧美国产视频在线| 亚洲第一成人网站| 久久新电视剧免费观看| 中文人妻一区二区三区| 国产色一区二区| 国产免费看av| 久久久久久久久久久电影| 成年人网站免费在线观看| 99精品久久99久久久久| 国产精品久久久久久在线观看| 国产精品一区二区三区四区 | 成人av网址在线| 极品白嫩少妇无套内谢| 国产91精品在线观看| 国产免费一区二区三区最新6| 国产福利91精品一区| www.欧美激情.com| 美美哒免费高清在线观看视频一区二区| 一起操在线视频| 紧缚捆绑精品一区二区| 亚洲精品在线网址| 国产精品亚洲成人| 老司机av网站| 国产在线精品一区二区不卡了 | 日韩精品国产精品| 日日噜噜噜噜久久久精品毛片| 日本欧美一区二区三区乱码| 一区二区三区视频网| 国产成人小视频| 在线中文字日产幕| 99精品国产91久久久久久| 欧美做受喷浆在线观看| 欧美激情综合在线| 久久久久久久久久网站| 亚洲高清免费在线| 中文字幕精品无码一区二区| 欧美日韩国产一级| 国产区精品在线| 亚洲成人激情图| 国产91久久久| 日韩大陆欧美高清视频区| 国产大片在线免费观看| 中文字幕亚洲欧美在线| 午夜伦理大片视频在线观看| 久久久视频在线| 不卡一二三区| 成人伊人精品色xxxx视频| 欧美亚洲色图校园春色| 亚洲精品一区二区三区樱花| 一区二区三区四区电影| 97av中文字幕| 亚洲男人影院| 欧美一级视频在线| 成人教育av在线| 国产在线综合视频| 亚洲黄色录像片| 日本三级一区二区三区| 日韩一级二级三级| 免费动漫网站在线观看| 久久成人精品视频| 日韩av影片| 成人综合国产精品| 欧美三级电影在线| 视色,视色影院,视色影库,视色网| 国产精品久久久免费| 57pao国产成永久免费视频| 久久久久久综合| 加勒比婷婷色综合久久| 91福利国产成人精品照片| 三级网站免费观看| 按摩亚洲人久久| jk漫画禁漫成人入口| 91精品久久久久久综合乱菊| 日韩母乳在线| 中文字幕色呦呦| 久久国产一二区| 日韩无码精品一区二区| 亚洲天天做日日做天天谢日日欢| 最新中文字幕一区| 亚洲韩国青草视频| 午夜伦理在线视频| 国产欧美日韩精品丝袜高跟鞋| 国产一区二区三区天码| 欧美精品久久久久久久自慰 | 日韩免费观看在线观看| 999精品嫩草久久久久久99| 亚洲.欧美.日本.国产综合在线| 亚洲少妇在线| 美女伦理水蜜桃4| 一区二区三区精品视频在线| 国产又大又粗又硬| 在线看福利67194| 色天使综合视频| 牛人盗摄一区二区三区视频| 精品99视频| 国产精品久久无码| 亚洲大片精品永久免费| 国内精品国产成人国产三级| 精品中文字幕视频| 中文字幕日本一区| 一本一道久久a久久精品综合 | 在线观看免费不卡av| 国产欧美日韩在线观看| 国产一级18片视频| 亚洲视频精品在线| 日韩av中字| 亚洲美女搞黄| 美女视频网站久久| 国产性猛交xx乱| 欧美一级夜夜爽| 亚洲男同gay网站| 91久久国产自产拍夜夜嗨| 亚洲国产99| 中文字幕人妻一区二区三区| 亚洲一区av在线| 日韩av成人| 日韩av黄色在线观看| 国产一区二区三区四区| 校园春色 亚洲色图| 国产精品嫩草影院av蜜臀| 中文字幕在线观看视频一区| 久久99久久99精品中文字幕| 亚洲成人影音| 欧美综合在线播放| 久久久国产一区二区三区四区小说| 无码人妻久久一区二区三区不卡| 亚洲图片在线综合| 精品国产三区在线| 男人天堂av片| 久久亚洲精品小早川怜子| 91国偷自产中文字幕久久| 久久久91精品国产| 98视频精品全部国产| 久久婷婷五月综合色国产香蕉| 国产午夜三级一区二区三| 伊人成人在线观看| 久久久久亚洲精品| 亚洲宅男网av| 一区二区在线免费看| 一区二区三区四区视频精品免费| 蜜桃av噜噜一区二区三区麻豆| 日韩av电影中文字幕| 久久理论电影| 久久久久99人妻一区二区三区| 日本精品一区二区三区高清 | japansex久久高清精品| 男女猛烈激情xx00免费视频| 国产婷婷精品av在线| 成人av无码一区二区三区| 欧美一区深夜视频| 婷婷综合在线| 最近中文字幕免费|