事件流描述的是從頁面中接收事件的順序。javascript
IE中的事件流叫作冒泡,即時間最開始由最具體的元素接收,而後逐級向上傳播到較爲不具體的節點,直到傳播到document對象。
例:html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Event Exampple</title> </head> <body> <div id="myDiv">click</div> </body> </html>
若是單擊頁面中div元素,那麼click時間會按照如下順序發生:java
<div>瀏覽器
<body>函數
<html>性能
documentspa
圖解事件冒泡過程:
code
事件捕獲的思想是不太具體的節點應該更早接收到事件,而最具體的節點應該最後接收到事件。htm
以上面html頁面爲例,若是單擊頁面中div元素,那麼click時間會按照如下順序發生:對象
document
<html>
<body>
<div>
圖解事件捕獲過程:
"DOM2級事件流"規定的事件包括三個階段:事件捕獲階段,處於目標階段,事件冒泡階段。
以上面html頁面爲例,單擊div元素會按照如下順序觸發事件:
如下是一個跨瀏覽器的事件處理程序
var eventUtil = { // 添加事件處理程序 addHandler: function(element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); //DOM } else if (element.attachEvent) { element.attachEvent('on' + type, handler); //IE } else { element['on' + type] = handler; } }, // 移除事件處理程序(經過addEventListener添加的匿名函數沒法移除) removeHandler: function(element, type, handler) { if (element.removeEventListener) { element.removeEventListener(type, handler, false); //DOM } else if (element.detachEvent) { element.detachEvent('on' + type, handler); //IE } else { element['on' + type] = null; } }, //獲取事件 getEvent: function(event) { return event ? event : window.event; }, //獲取事件類型 getType: function(event) { return event.type; }, //獲取事件源 getElement: function(event) { return event.target || event.srcElement; }, //阻止默認事件好比a連接跳轉 preventDefault: function(event) { if (event.preventDefault) { event.preventDefault(); } else { event.returnValue = false; } }, //阻止事件冒泡 stopPropagation: function(event) { if (event.stopPropagation) { event.stopPropagation(); } else { event.cancelBubble = true; } } }
事件委託是利用事件冒泡原理,指定一個事件處理程序,就能夠管理某一類型的全部事件。
添加在頁面上的事件處理程序的數量直接關係到頁面的總體運行性能,首先,事件處理函數都是對象,其數量越多,佔用內存就越大,則性能就越差。其次,必須事先指定全部事件處理程序而致使的DOM訪問次數,會延遲整個頁面的交互就緒時間。
//html <ul id="myLinks"> <li id="goSomewhere">Go somewhere</li> <li id="doSomething">Do something</li> <li id="sayHi">Say hi</li> </ul> //傳統添加事件方法 <script type="text/javascript"> var item1 = document.getElementById("goSomewhere"); var item2 = document.getElementById("doSomething"); var item3 = document.getElementById("sayHi"); EventUtil.addHandler(item1,"click",function(event){ location.href = "http://www.baidu.com"; }); EventUtil.addHandler(item2,"click",function(event){ document.title = "changed the dicument's title"; }); EventUtil.addHandler(item3,"click",function(event){ alert("hi"); }); </script> //事件委託方法 <script type="text/javascript"> var list = document.getElementById("myLinks"); EventUtil.addHandler(item1,"click",function(event){ event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); switch(target.id){ case "goSomewhere": document.title = "changed the dicument's title"; break; case "doSomething": location.href = "http://www.baidu.com"; break; case "sayHi": alert("hi"); break; } });
時間委託相比傳統添加事件監聽的優勢:
在頁面中設置事件處理程序所需的時間更少,只添加一個時間處理程序所需的DOM引用次數更少,所花的時間更少。
整個頁面佔用的內存空間更少,可以提高總體性能。