事件流描述的是从页面中接收事件的顺序。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引用次数更少,所花的时间更少。
整个页面占用的内存空间更少,可以提高总体性能。