你的位置:首页 > Java教程

[Java教程]javascript事件委托

在引入事件委托之前,首先来看下面这个例子:点击改变li的背景颜色。

<ul id="container">  <li>1</li>  <li>2</li>  <li>2</li>  <li>3</li>  <li>4</li></ul>

  window.onload = function () {    var liLis = document.getElementsByTagName('li');    for (var i = 0; i < liLis.length; i++) {      //addEventListener不兼容ie9以下版本,请自行用attachEvent做兼容处理      liLis[i].addEventListener('click', function (ev) {        //兼容ie低版本        var ev = ev || window.event;        var target = ev.target || ev.srcElement;        target.style.background = 'red';      }, false)    }  }

上面可以做到,点击li,改变li的背景颜色为红色。但是请思考一个问题,如果页面存在很多的li,那么使用for循环给所有的li都绑定click事件的话就将直接影响到页面的整体运行性能,原因是每个函数都是对象,都会占用内存,内存中的对象越多,性能就越差,其次事先指定所有事件处理程序而导致DOM访问次数,会延迟整个页面的交互就绪时间。针对“事件处理程序过多”这个问题,事件委托这个解决方案就诞生了。
 
那么什么是事件委托呢?事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。说简单点儿,上面的click事件我不用给每个li都绑定,只需在ul(DOM树中尽量高的层次上)上绑定一个click事件,就可以管理所有li的click事件。
下面请看实现代码。
  window.onload = function () {    var ul = document.getElementById('container');    //addEventListener不兼容ie9以下版本,请自行用attachEvent做兼容处理    ul.addEventListener('click', function (ev) {      //兼容ie低版本      var ev = ev || window.event;      var target = ev.target || ev.srcElement;      //nodeName:找到元素标签名      if (target.nodeName.toLowerCase() == 'li') {        target.style.background = 'green';      }    }, false)  }

上面这么做的好处:页面中设置事件处理程序所需时间更少,只添加一个事件处理程序所需的DOM引用更少,所花的时间也更少;整个页面占用的内存空间更少,能够提升整体性能。
 
注意:1.对于使用appendChild方法添加的元素,在使用事件委托后,也能够绑定上事件;2,最适合采用事件委托技术的事件包括click、mousedown、mouseup、keydown、keyup和keypress。虽然mouseover和mouseout事件也冒泡,但是要适当处理它们并不容易,而且经常需要计算元素的位置。(因为当鼠标从一个元素移到其子节点时,或者当鼠标移出该元素时,都会触发mouseout事件  )这点请读者自行验证。