DOM事件模型
事件流又称为事件传播,描述的是从页面中接收事件的顺序。DOM2 级事件规定事件流包括三个阶段: 事件捕获(capturing phase)、目标事件(target phase)、事件冒泡(bubbling phase)。
发生的顺序是:事件捕获阶段 --> 目标事件阶段 --> 事件冒泡阶段
- 事件冒泡
Event bubble
事件开始时由最具体的元素(目标元素)接收,然后逐级向上传播。
- 事件捕获
Event Capture
事件按 window -> document -> html -> body -> ... -> 目标元素 的方向向下层元素传递。
- 事件对象参数
event
在用户触发事件,执行事件处理函数的时候,默认会向事件处理函数传入一个 event 对象,它记录了该事件的状态和行为。
常用的event属性与方法
type 事件类型
target 事件发出者(触发事件的元素)
currentTarget 事件监听者(被绑定事件的元素)
stopPropagation() 阻止事件冒泡或捕获
preventDefault() 阻止浏览器默认行为
事件委托
一般来说,dom需要有事件处理程序,我们都会直接给它设事件处理程序就好了,那如果是很多的dom需要添加事件处理呢?比如我们有100个li,每个li都有相同的click点击事件,可能我们会用for循环的方法,来遍历所有的li,然后给它们添加事件。
但这样就会不断与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托(利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件),与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
- 普通事件绑定
<ul id="wrap">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
window.onload = function(){
var oUl = document.getElementById("wrap");
var aLi = oUl.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = function(){
alert(123);
}
}
}
- 事件委托
window.onload = function(){
var oUl = document.getElementById("wrap");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}