通過前段時間的準備,筆者最近已經成功入職shopee。因此最近沒有更新內容,以後穩定下來以後會繼續進行輸出node
入職shopee以後,導師有給到一個entry task,這個任務是實現一個事件機制。實現addEventListener
,removeEventListener
,dispatchEvent
這三個方法。api
要求是這個樣子的:數組
加分項有個比較有意思的東西:儘量保證一幀的時間(16ms)中全部事件的執行時間之和不超過 10ms(暫時無需考慮超過 10ms 的單個事件),須要把在這一幀來不及執行的事件放到下一幀執行(依舊須要按照優先級來執行)
緩存
W3C的事件模型是先捕獲後冒泡微信
入參爲dom節點,監聽方法名,回調方法,其餘配置能夠用...opt接受。數據結構
實現思路
:dom
將註冊的事件同一處理,建立weakmap對象,數據結構以下:函數
{ Dom:{ handleName(監聽方法名):{ // 存放處理捕獲和冒泡的數組 bubble:[{ // 冒泡數組 cb:()=>void // 事件觸發回調 range:0 // 此事件優先級 once:false // 兼容opt的once參數 }], capture:[] // 捕獲數組,同上 } } }
方法內部還須要對原來的dom節點進行一次監聽,用來在用戶手動點擊觸發時的事件。這時候須要將此事件作一個緩存,以便在removeEventListener
的時候去取消監聽學習
入參爲dom節點,監聽方法名,回調,是否採用捕獲模型(可選,默認false)spa
實現思路:
首先是健壯性處理,而後對weakmap對象中對應節點的對應事件作刪除處理。而後把在addEventListener
的時候添加的監聽進行remove。
這個方法應該算是關鍵,他的入參是dom節點和監聽方法名。
實現思路:
這裏能夠提供一下個人思路,你們也能夠本身嘗試寫一下。
// 遞歸的去將當前節點和父節點存入數組 function recurrenceFindNodeList( caps: callbackType[], bubs: callbackType[], node: nodeType, handleName: string ) { const parent: any = node.parentNode; if (eventMap.has(parent)) { const parentObj = eventMap.get(parent)[handleName]; caps = [...parentObj.capture, ...caps]; bubs = [...bubs, ...parentObj.bubble]; recurrenceFindNodeList(caps, bubs, parent, handleName); } return [...caps, ...bubs]; } // 對於10ms 的實現 requestAnimationFrame(handler); function handler(time: number) { let taskFinishTime: number = window.performance.now(); while (taskFinishTime - time < 10) { const nextTask = tasklist.shift(); if (nextTask?.cb) { nextTask.cb(); } taskFinishTime = window.performance.now(); } if (tasklist.length > 0) { requestAnimationFrame(handler); } }
shopee是一個很是年輕化的公司,在這裏從技術角度說,能夠學習到不少新技術,並參加他們的項目從0到1的過程,相信在這裏的進步會很大。若是你們想了解蝦皮歡迎加我微信:zhi794855679 。
願不負努力,所願皆所求。