簡介: 事件處理是 Ajax 應用中的重要組成部分,也是應用動態變化的源動力。本文詳細介紹了瀏覽器中的事件處理相關的內容,包括註冊事件監聽器、事件發生之後的傳播機制、編寫事件監聽器等,還介紹了 Dojo 對事件處理提供的支援。最後介紹了與瀏覽器記憶體泄露和效能相關的最佳實務。
瀏覽器中的事件是 Ajax 應用動態變化的源動力。使用者通過輸入裝置(主要是鍵盤和滑鼠)與應用進行互動。對於使用者不同的動作,如點擊滑鼠左鍵、右鍵、或是按下鍵盤上的斷行符號鍵,瀏覽器會產生與之對應的事件。這些事件按照一定的規則在當前文檔樹中傳播。應用可以根據自己的需要,對特定的事件進行處理,以響應使用者的動作。這種事件驅動的方式,不僅在 Web 應用程式中被使用,在案頭應用中也廣泛流行。本文詳細介紹了瀏覽器中事件處理的各個方面,包括事件監聽器的註冊、事件的傳播、事件處理和其它進階話題。本文還介紹了如何使用 Dojo 提供的 dojo.connect()。本文中使用的 Dojo 版本是 1.4。下面首先介紹如何註冊事件監聽器。
註冊事件監聽器
註冊事件監聽器的目的是在事件發生的時候添加相應的處理邏輯。瀏覽器中的事件處理採用經典的觀察者(Observer)設計模式。對於可能產生的各種事件,Ajax 應用通過指令碼在節點上關注自己感興趣的事件,並添加相應的處理邏輯。當相應的事件發生並傳播到監聽器註冊的節點時,處理邏輯會被調用。
由於曆史原因、瀏覽器之間的相容性問題以及 W3C 的標準化工作,目前註冊事件監聽器的方式主要有三種,分別是 DOM 層級 0 定義的方式、W3C 規範定義的事件模型和 IE 專屬的事件模型。下面分別對這三種方式進行詳細的介紹。
DOM 層級 0 定義的方式
這種事件監聽器註冊方式是把事件處理方法作為 DOM 節點對象的屬性來設定。設定屬性就相當於為對應的事件註冊了監聽器。DOM 節點對象有不同的屬性與不同的事件類型相對應,如 onclick對應於滑鼠的點擊、onsubmit對應於表單的提交、onkeydown對應於鍵盤上的鍵被按下等。
這種事件監聽器註冊方式由於出現得最早,有著很好的瀏覽器安全色性,使用起來也比較簡單。它的問題是由於事件處理方法被設定為 DOM 節點對象的屬性,因此對一個 DOM 節點的每種事件,最多隻能有一個事件處理方法。之後設定的方法會覆蓋掉之前的方法。對於一個多人開發的比較複雜的 Ajax 應用來說,這會是一個不小的問題。很可能某個開發人員添加的事件處理方法被另外的開發人員無意中覆蓋,造成難以調試的問題。另外這種方式只支援事件的冒泡階段,不支援捕獲階段。
W3C 規範定義的事件模型
在 W3C 的 DOM 層級 2 規範中引入了與瀏覽器事件相關的內容。這其中一個重要的介面就是 EventTarget,用來表示一個事件的目標。對於一個事件目標,可以在其上註冊多個事件監聽器。DOM 中的節點(Node)實現了此介面。因此,文檔樹中的任何節點都可以作為事件目標,從而在其上註冊事件監聽器。註冊事件監聽器是通過 EventTarget介面的 addEventListener(type, listener, useCapture)方法來完成的。該方法的參數 type表示的是事件的類型,如 click、submit和 keypress等;參數 listener表示的是事件的處理方法;參數 useCapture表示是否啟用事件捕獲。這三個參數都是必須的。關於事件捕獲和冒泡的細節,下面章節會介紹。與 addEventListener()對應的是 removeEventListener(),用來從事件目標中刪除監聽器,其參數與 addEventListener()相同。
使用 W3C 規範定義的事件模型的最大好處是可以為每個節點的每個事件註冊多個監聽器。這些監聽器不會互相影響。當事件發生的時候,這些監聽器都會被觸發,但是具體的順序是不確定的。另外這也是符合標準的做法,並且同時支援事件的捕獲和冒泡。不過最大的問題是 IE 並不支援此事件模型。
IE 專屬的事件模型
IE 採用了與 W3C 規範不同的事件模型。該模型與 W3C 規範定義的事件模型有點類似。它使用 attachEvent(type, listener)和 detachEvent(type, listener)兩個方法來完成事件監聽器的註冊和刪除。與 W3C 規範中的 addEventListener()和 removeEventListener()方法相比,這兩個方法都少了一個參數。這是由於 IE 並不支援事件的捕獲。另外事件的類型也必須以“on”開頭,如 onclick、onsubmit和 onkeypress等。
IE 專屬的事件模型也支援為每個元素的每個事件註冊多個監聽器。不過該模型只在 IE 中有效,在其它瀏覽器中,需要使用 W3C 規範定義的事件模型。
代碼清單 1 中給出了如何分別使用這三種方式為一個元素註冊滑鼠點擊事件的監聽器。
清單 1. 三種事件監聽器註冊方式樣本
var node = document.getElementById("myDiv");
node.onclick = function() {
alert("DOM 層級 0 事件註冊");
};
if (node.addEventListener) {
node.addEventListener("click", function() {
alert("W3C 事件模型");
}, false);
}
if (node.attachEvent) {
node.attachEvent("onclick", function() {
alert("IE 事件模型");
});
}
在介紹了如何註冊事件監聽器之後,下面介紹事件發生之後在當前文檔樹中的傳播方式。