DOM事件

154 阅读2分钟

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);
    }
  }
}