• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    淺談React Event實現原理

    來源:懂視網 責編:小采 時間:2020-11-27 22:07:25
    文檔

    淺談React Event實現原理

    淺談React Event實現原理:React 元素的事件處理和 DOM元素的很相似。但是有一點語法上的不同: React事件綁定屬性的命名采用駝峰式寫法,而不是小寫。 如果采用 JSX 的語法你需要傳入一個函數作為事件處理函數,而不是一個字符串(DOM元素的寫法) 并且 React 自己內部實現了一
    推薦度:
    導讀淺談React Event實現原理:React 元素的事件處理和 DOM元素的很相似。但是有一點語法上的不同: React事件綁定屬性的命名采用駝峰式寫法,而不是小寫。 如果采用 JSX 的語法你需要傳入一個函數作為事件處理函數,而不是一個字符串(DOM元素的寫法) 并且 React 自己內部實現了一

    runEventQueuelnBatch(events)做了兩件事

    1. 把 dispatchListener里面的事件排隊push進 eventQueue
    2. 執行 EventPluginHub.processEventQueue(false);

    執行的細節如下:

    EventPluginHub.js

     // 循環 eventQueue調用
     var executeDispatchesAndReleaseTopLevel = function (e) {
     return executeDispatchesAndRelease(e, false);
     };
     /* 從event._dispatchListener 取出 dispatchlistener,然后dispatch事件,
     * 循環_dispatchListeners,調用executeDispatch
     */
     var executeDispatchesAndRelease = function (event, simulated) {
     if (event) {
     // 在這里dispatch事件
     EventPluginUtils.executeDispatchesInOrder(event, simulated);
     // 釋放事件
     if (!event.isPersistent()) {
     event.constructor.release(event);
     }
     }
     };
    
     enqueueEvents: function (events) {
     if (events) {
     eventQueue = accumulateInto(eventQueue, events);
     }
     },
    
     /**
     * Dispatches all synthetic events on the event queue.
     *
     * @internal
     */
     processEventQueue: function (simulated) {
     // Set `eventQueue` to null before processing it so that we can tell if more
     // events get enqueued while processing.
     var processingEventQueue = eventQueue;
     eventQueue = null;
     if (simulated) {
     forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
     } else {
     forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
     }
     // This would be a good time to rethrow if any of the event fexers threw.
     ReactErrorUtils.rethrowCaughtError();
     },
    /**
     * Standard/simple iteration through an event's collected dispatches.
     */
    function executeDispatchesInOrder(event, simulated) {
     var dispatchListeners = event._dispatchListeners;
     var dispatchInstances = event._dispatchInstances;
    
     if (Array.isArray(dispatchListeners)) {
     for (var i = 0; i < dispatchListeners.length; i++) {
     // 由這里可以看出,合成事件的stopPropagation只能阻止react合成事件的冒泡,
     // 因為event._dispatchListeners 只記錄了由jsx綁定的綁定的事件,對于原生綁定的是沒有記錄的
     if (event.isPropagationStopped()) {
     break;
     }
     // Listeners and Instances are two parallel arrays that are always in sync.
     executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]);
     }
     } else if (dispatchListeners) {
     executeDispatch(event, simulated, dispatchListeners, dispatchInstances);
     }
     event._dispatchListeners = null;
     event._dispatchInstances = null;
    }
    function executeDispatch(event, simulated, listener, inst) {
     var type = event.type || 'unknown-event';
     // 注意這里將事件對應的dom元素綁定到了currentTarget上
     event.currentTarget = EventPluginUtils.getNodeFromInstance(inst);
     if (simulated) {
     ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event);
     } else {
     // 一般都是非模擬的情況,執行invokeGuardedCallback
     ReactErrorUtils.invokeGuardedCallback(type, listener, event);
     }
     event.currentTarget = null;
    }

    由上面的函數可知,dispatch 合成事件分為兩個步驟:

    1. 通過_dispatchListeners里得到所有綁定的回調函數,在通過_dispatchInstances的綁定回調函數的虛擬dom元素
    2. 循環執行_dispatchListeners里所有的回調函數,這里有一個特殊情況,也是react阻止冒泡的原理

    其實在 EventPluginHub.js 里主要做了兩件事情.

    1.從event._dispatchListener 取出 dispatchlistener,然后dispatch事件,
    循環_dispatchListeners,調用executeDispatch,然后走到ReactErrorUtils.invokeGuardedCallback;
    2.釋放 event

    上面這個函數最重要的功能就是將事件對應的dom元素綁定到了currentTarget上,

    這樣我們通過e.currentTarget就可以找到綁定事件的原生dom元素。

    下面就是整個執行過程的尾聲了:

    ReactErrorUtils.js

    var fakeNode = document.createElement('react');
    ReactErrorUtils.invokeGuardedCallback = function(name, func, a, b) {
     var boundFunc = func.bind(null, a, b);
     var evtType = `react-${name}`;
     fakeNode.addEventListener(evtType, boundFunc, false);
     var evt = document.createEvent('Event');
     evt.initEvent(evtType, false, false);
     fakeNode.dispatchEvent(evt);
     fakeNode.removeEventListener(evtType, boundFunc, false);
     };

    由invokeGuardedCallback可知,最后react調用了faked元素的dispatchEvent方法來觸發事件,并且觸發完畢之后立即移除監聽事件。

    總的來說,整個click事件被分發的過程就是:

    1、用EventPluginHub生成合成事件,這里注意同一事件類型只會生成一個合成事件,里面的_dispatchListeners里儲存了同一事件類型的所有回調函數

    2、按順序去執行它

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    淺談React Event實現原理

    淺談React Event實現原理:React 元素的事件處理和 DOM元素的很相似。但是有一點語法上的不同: React事件綁定屬性的命名采用駝峰式寫法,而不是小寫。 如果采用 JSX 的語法你需要傳入一個函數作為事件處理函數,而不是一個字符串(DOM元素的寫法) 并且 React 自己內部實現了一
    推薦度:
    標簽: 原理 event 機制
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 精品人妻系列无码天堂| 国产成人精品精品欧美| 囯产精品一品二区三区| 九九线精品视频在线观看| 国产精品嫩草视频永久网址| 亚洲人精品午夜射精日韩| 午夜精品视频在线| 成人午夜视频精品一区| 亚洲精品成人无限看| 久久无码人妻精品一区二区三区 | 国产精品ⅴ无码大片在线看| 日韩精品一二三区| 国产精品1024在线永久免费| 国产99精品久久| 国产精品久久久久国产A级| 亚洲国产精品SSS在线观看AV| 亚洲国产成人精品无码久久久久久综合 | 久久99精品久久久久久久不卡 | 99久久99久久精品国产| 久久精品国产99国产精品澳门 | 国产乱子伦精品无码码专区| 亚洲精品无码午夜福利中文字幕| 久久亚洲AV永久无码精品| 国产在AJ精品| 国产观看精品一区二区三区| 青青青国产依人精品视频| 精品国产第1页| 国产精品久久久久影院色| 国产短视频精品一区二区三区| 精品人妻人人做人人爽| 国产亚洲欧美精品久久久| AV无码精品一区二区三区| 精品无码一区二区三区爱欲| 久久亚洲精品中文字幕| 精品久久久无码中文字幕| 亚洲国产精品久久久久婷婷老年| 91精品国产91久久综合| 国产精品福利一区二区久久| 久久国产成人精品麻豆| 91精品国产品国语在线不卡| 91嫩草亚洲精品|