事件委托

“过多事件处理程序”的解决方案是使用事件委托。事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。
通过在父级元素绑定事件,由子元素触发冒泡至父级。父级事件函数通过事件源对象 targetsrcELemnt 操作子元素。

  1. /*HTML:
  2. <ul>
  3. <li>1</li>
  4. <li>2</li>
  5. <li>3</li>
  6. ...
  7. <li>100</li>
  8. </ul>
  9. */
  10. oUl.onclick = function(e){
  11. var e = e || window.event,
  12. tar = e.target || e.srcElement;
  13. if(tar.nodeName.toLowerCase() == 'li') { //筛选出目标的子元素集合
  14. // ...
  15. }
  16. }

只要可行,就应该考虑只给 document 添加一个事件处理程序,通过它处理页面中所有某种类型的事件。相对于之前的技术,事件委托具有如下优点。

  • document 对象随时可用,任何时候都可以给它添加事件处理程序(不用等待 DOMContentLoaded或 load 事件)。这意味着只要页面渲染出可点击的元素,就可以无延迟地起作用。
  • 节省花在设置页面事件处理程序上的时间。只指定一个事件处理程序既可以节省 DOM 引用,也可以节省时间。
  • 减少整个页面所需的内存,提升整体性能。

    删除事件处理程序

    把事件处理程序指定给元素后,在浏览器代码和负责页面交互的 JavaScript 代码之间就建立了联系。
    这种联系建立得越多,页面性能就越差。除了通过事件委托来限制这种连接之外,还应该及时删除不用的事件处理程序。
    很多 Web 应用性能不佳都是由于无用的事件处理程序长驻内存导致的。

  • 删除带有事件处理程序的元素,如果被删除的元素上带有事件处理程序,就不会被垃圾程序正常清理。

  • 如果在页面卸载后事件处理程序没有被清理,则它们仍然会残留在内存中。之后,浏览器每次加载和卸载页面(比如通过前进、后退或刷新),内存中残留对象的数量都会增加,这是因为事件处理程序不会被回收。