JavaScript事件在WebKit中的處理流程研究

來源:互聯網
上載者:User

JavaScript事件在WebKit中的處理流程研究

本文主要探討了JavaScript事件在WebKit中的註冊和觸發機制。

JS事件有兩種註冊方式: 通過DOM節點的屬性添加或者通過node.addEventListener()函數註冊;

通過DOM節點的屬性添加如下所示,節點的屬性採用on後面緊接event name的形式,比如onclick, onload;

 

<script type=text/javascript> function listener(e){ alert(hello world!); }</script>click

 

通過addEventListener()函數註冊的形式如下, 其完整的形式是:target.addEventListener(type, listener[, useCapture]);其中type為事件類型,listener為響應函數, useCapture表示是否在capture階段觸發,如果不指定,則為false;

 

button<script type=text/javascript> document.getElementById('button').addEventListener(click, listener);</script>

 

WebKit中事件相關的類別關係如所示:

1. EventTargetDatatMap: 全域對應表,建立了Node與EventTargetData之間的映射關係 ;

2. EventTargetData: 成員變數firingEventIterators是Vector, 用於記錄正在觸發的事件類型,當該Vector非空時,也表示當前正處於firing階段; 成員變數eventListenerMap是EventlListenerMap類型;

3. EventlListenerMap:按事件類型分類儲存了EventListeners; 成員變數m_entires是Vector,其中每一項可以簡化為std::pair類型;

4. JSLazyEventListener: 最終響應事件觸發的對象; 儲存了JS執行的基本資料(源碼或者JSObject類型的函數對象);

 

第一種情況下,開始事件註冊的時機是發生在頁面解析階段,當建立對了button元素以後,解析到onclick屬性,會根據屬性值建立對應的EventListener; 這種情況下的EventListener僅儲存了JS源碼(還沒有轉換成JSC虛擬機器內部的函數對象), 並將EventListener添加到全域Hash表中;

第二種情況下,JS在虛擬機器中執行到”addEventListener()時,會根據JSBindings建立的映射關係,最終調用到WebCore中的native實現Node::addEventListener(), 該函數會根據虛擬機器中傳遞過來的函數對象建立EventListener,並在全域Hash表中建立起target node與EventListener(即這裡的button)的映射關係;

是兩種情況下,事件註冊的流程對比:

 

事件觸發流程有以下幾個步驟:

1. 找到響應事件的target node: 如果是使用者互動事件,通過Hit Test演算法確定; 如果是瀏覽器內部產生的事件,一般有固定的響應節點,比如load事件的target node是body節點;

2. 事件分發:事件在document與target之間按照(capture, at_target, bubble)的順序進行分發,capture按照從根節點document到子節點target的路徑,而bubble則相反;

3. 事件響應:分發流程中,如果事件分發到的當前節點註冊了該類型的事件,並且useCapure與事件的分發的順序一致(即capture階段時,當前節點註冊了useCapture == true的事件), 則進行事件響應; 事件響應分成兩步: (1) 從全域對應表中找到當前node對應的EventListeners;(2)將EventListeners封裝的JS(源碼或者JSC的函數對象)拋到JS虛擬機器中執行(是mouseup事件的觸發時序):

 

 

如前所述,屬性中註冊的事件在EventListener中僅儲存了源碼,所以開始執行之前會對源碼進行必要的轉換,格式化成如下形式:

 

 

      (function(event) {listener(event)})

簡單來講,事件註冊是建立node與響應函數的映射關係的過程 ,這種映射關係基於事件類型進行分類; 而事件觸發則是基於這種映射關係,在不同階段(capture, bubble)響應註冊函數的過程;

 

 

 


 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.