一、什麼是事件?html
事件,就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間。可使用偵聽器(或處理程序)來預訂事件,以便事件發生時執行相應的代碼。這種在傳統軟件工程中被稱爲觀察員模式的模型,支持頁面的行爲(JavaScript 代碼)與頁面的外觀(HTML 和CSS 代碼)之間的鬆散耦合。DOM2 級規範開始嘗試以一種符合邏輯的方式來標準化DOM事件。瀏覽器
二、什麼是事件流?函數
事件冒泡:IE 的事件流叫作事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上傳播到較爲不具體的節點(文檔)。如:this
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Event Bubbling Example</title> 5 </head> 6 <body> 7 <div id="myDiv">Click Me</div> 8 </body> 9 </html>
事件觸發順序爲:spa
事件捕獲:Netscape Communicator 團隊提出的另外一種事件流叫作事件捕獲(event capturing)。事件捕獲的思想是不太具體的節點應該更早接收到事件,而最具體的節點應該最後接收到事件。事件捕獲的用意在於在事件到達預約目標以前捕獲它。code
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Event Bubbling Example</title> 5 </head> 6 <body> 7 <div id="myDiv">Click Me</div> 8 </body> 9 </html>
事件觸發順序爲:htm
「DOM2級事件」規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。首先發生的是事件捕獲,爲截獲事件提供了機會。而後是實際的目標接收到事件。最後一個階段是冒泡階段,能夠在這個階段對事件作出響應。如:對象
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Event Bubbling Example</title> 5 </head> 6 <body> 7 <div id="myDiv">Click Me</div> 8 </body> 9 </html>
總事件觸發順序爲:blog
三、什麼是事件處理程序?seo
事件就是用戶或瀏覽器自身執行的某種動做。諸如click、load 和mouseover,都是事件的名字。而響應某個事件的函數就叫作事件處理程序(或事件偵聽器)。事件處理程序的名字以"on"開頭,所以click 事件的事件處理程序就是onclick,load 事件的事件處理程序就是onload。爲事件指定處理程序的方式有好幾種。
3.1 、DOM0級事件處理程序
經過JavaScript 指定事件處理程序的傳統方式,就是將一個函數賦值給一個事件處理程序屬性。這種爲事件處理程序賦值的方法是在第四代Web 瀏覽器中出現的,並且至今仍然爲全部現代瀏覽器所支持。緣由一是簡單,二是具備跨瀏覽器的優點。要使用JavaScript 指定事件處理程序,首先必須取得一個要操做的對象的引用。綁定"onclick"方法,如:
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(){ 3 alert("Clicked");
4 };
解除綁定"onclick"方法,如:
1 btn.onclick = null;
3.二、DOM2 級事件處理程序
「DOM2級事件」定義了兩個方法,用於處理指定和刪除事件處理程序的操做:addEventListener()和removeEventListener()。全部DOM節點中都包含這兩個方法,而且它們都接受3 個參數:要處理的事件名、做爲事件處理程序的函數和一個布爾值。最後這個布爾值參數若是是true,表示在捕獲階段調用事件處理程序;若是是false,表示在冒泡階段調用事件處理程序。
要在按鈕上爲click 事件添加事件處理程序(冒泡),可使用下列代碼:
1 var btn = document.getElementById("myBtn"); 2 btn.addEventListener("click", function(){ 3 alert(this.id); 4 }, false);
上面的代碼爲一個按鈕添加了onclick 事件處理程序,並且該事件會在冒泡階段被觸發(由於最後一個參數是false)。與DOM0 級方法同樣,這裏添加的事件處理程序也是在其依附的元素的做用域中運行。使用DOM2 級方法添加事件處理程序的主要好處是能夠添加多個事件處理程序。來看下面的例子。
1 var btn = document.getElementById("myBtn"); 2 btn.addEventListener("click", function(){ 3 alert(this.id); 4 }, false); 5 btn.addEventListener("click", function(){ 6 alert("Hello world!"); 7 }, f alse);
這裏爲按鈕添加了兩個事件處理程序。這兩個事件處理程序會按照添加它們的順序觸發,所以輸出:
1 myBtn 2 Hello world!
經過addEventListener()添加的事件處理程序只能使用removeEventListener()來移除;移除時傳入的參數與添加處理程序時使用的參數相同。這也意味着經過addEventListener()添加的匿名函數將沒法移除。
匿名函數將沒法移除,以下面的例子所示。
1 var btn = document.getElementById("myBtn"); 2 btn.addEventListener("click", function(){ 3 alert(this.id); 4 },false); 5 6 //這裏省略了其餘代碼 7 8 btn.removeEventListener("click", function(){ //沒有用! 9 alert(this.id); 10 }, false);
在這個例子中,咱們使用addEventListener()添加了一個事件處理程序。雖然調用removeEventListener()時看似使用了相同的參數,但實際上,第二個參數與傳入addEventListener()中的那一個是徹底不一樣的函數。而傳入removeEventListener()中的事件處理程序函數必須與傳入addEventListener()中的相同,以下面的例子所示。
正確作法是,請看下面例子:
1 var btn = document.getElementById("myBtn"); 2 var handler = function(){ 3 alert(this.id); 4 }; 5 btn.addEventListener("click", handler, false); 6 //這裏省略了其餘代碼 7 btn.removeEventListener("click", handler, false); //有效!
重寫後的這個例子沒有問題,是由於在addEventListener()和removeEventListener()中使用了相同的函數。
3.2.一、IE事件處理程序
IE 實現了與DOM 中相似的兩個方法:attachEvent()和detachEvent()。這兩個方法接受相同的兩個參數:事件處理程序名稱與事件處理程序函數。因爲IE8 及更早版本只支持事件冒泡,因此經過attachEvent()添加的事件處理程序都會被添加到冒泡階段。
要使用attachEvent()爲按鈕添加一個事件處理程序,可使用如下代碼。
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(){ 3 alert("Clicked"); 4 });
注意,attachEvent()的第一個參數是"onclick",而非DOM 的addEventListener()方法中的"click"。
在IE 中使用attachEvent()與使用DOM0 級方法的主要區別在於事件處理程序的做用域。在使用DOM0 級方法的狀況下,事件處理程序會在其所屬元素的做用域內運行;在使用attachEvent()方法的狀況下,事件處理程序會在全局做用域中運行,所以this 等於window。來看下面的例子。
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(){ 3 alert(this === window); //true 4 });
與addEventListener()相似,attachEvent()方法也能夠用來爲一個元素添加多個事件處理程序。來看下面的例子。
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(){ 3 alert("Clicked"); 4 }); 5 btn.attachEvent("onclick", function(){ 6 alert("Hello world!"); 7 });
輸出:
1 Hello world! 2 Clicked
這裏調用了兩次attachEvent(),爲同一個按鈕添加了兩個不一樣的事件處理程序。不過,與DOM方法不一樣的是,這些事件處理程序不是以添加它們的順序執行,而是以相反的順序被觸發。單擊這個例子中的按鈕,首先看到的是"Hello world!",而後纔是"Clicked"。
使用attachEvent()添加的事件能夠經過detachEvent()來移除,條件是必須提供相同的參數。與DOM 方法同樣,這也意味着添加的匿名函數將不能被移除。不過,只要可以將對相同函數的引用傳給detachEvent(),就能夠移除相應的事件處理程序。例如:
1 var btn = document.getElementById("myBtn"); 2 var handler = function(){ 3 alert("Clicked"); 4 }; 5 btn.attachEvent("onclick", handler); 6 //這裏省略了其餘代碼 7 btn.detachEvent("onclick", handler);
注:支持該事件處理程序的只有IE和Opera
3.2.二、跨瀏覽器的事件處理程序
只需關注冒泡階段。第一個要建立的方法是addHandler(),它的職責是視狀況分別使用DOM0 級方法、DOM2 級方法或IE 方法來添加事件。這個方法屬於一個名叫EventUtil 的對象,本書將使用這個對象來處理瀏覽器間的差別。addHandler()方法接受3 個參數:要操做的元素、事件名稱和事件處理程序函數。
與addHandler()對應的方法是removeHandler(),它也接受相同的參數。這個方法的職責是移除以前添加的事件處理程序——不管該事件處理程序是採起什麼方式添加到元素中的,若是其餘方法無效,默認採用DOM0 級方法。
EventUtil 的用法以下所示。
1 var EventUtil = { 2 addHandler: function(element, type, handler){ 3 if (element.addEventListener){ 4 element.addEventListener(type, handler, false); 5 } else if (element.attachEvent){ 6 element.attachEvent("on" + type, handler); 7 } else { 8 element["on" + type] = handler; 9 } 10 }, 11 removeHandler: function(element, type, handler){ 12 if (element.removeEventListener){ 13 element.removeEventListener(type, handler, false); 14 } else if (element.detachEvent){ 15 element.detachEvent("on" + type, handler); 16 } else { 17 element["on" + type] = null; 18 } 19 } 20 };
能夠像下面這樣使用EventUtil 對象:
1 var btn = document.getElementById("myBtn"); 2 var handler = function(){ 3 alert("Clicked"); 4 }; 5 EventUtil.addHandler(btn, "click", handler); 6 //這裏省略了其餘代碼 7 EventUtil.removeHandler(btn, "click", handler);
今天的討論就到這裏,若是有什麼意見或者建議,請多留言哦!!!