聊聊事件委托

事件委托

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件

问题一:什么是事件冒泡?

事件开始时有最具体的元素(文档中嵌套层次最深的那个结点)接收,然后逐级传播到较为不具体的结点(文档)

DOM事件流

事件捕获阶段(事件由document对象首先接收,再到事件的实际目标)
事件发生阶段
事件冒泡阶段(与事件捕获顺序相反)

bubblecode
如以上代码所示,浏览器会依次提示5、4、3、2、1、0,click事件依次由内到外在每个元素上发生(同一类型的事件发生,事件冒泡顺序)

取消事件冒泡方法:

利用事件对象的方法 e.stopPropagation();
IE下 window.event.cancelBubble=true;

不冒泡事件:blur、focus、load、unload

如何使用事件委托

添加事件处理程序
DOM0级:

1
<a href="javascript:void(0)" onclick="handler()"/></a>

  • 默认以冒泡形式发生

var obj = document.getElementById(“obj”);
obj.onclick=function(){};
obj.onclick = null;

  • 一个元素只能添加一个事件处理程序,后面定义的会覆盖前面的。
  • 事件处理程序是在当前元素的作用域中运行。

DOM2级:
var obj = document.getElementById(“obj”);
obj.addEventListener(‘click’,function(){},false);

  • 第三参数false表示在冒泡阶段调用事件处理程序。true表示在捕获阶段捕获
  • 一个元素可以添加多个事件处理程序,这多个事件处理程序会”顺序触发”。
  • 事件处理程序是在当前元素的作用域中运行。移除事件处理程序时,传入参数要与添加时使用的参数相等。

IE下,方法分别为attachEvent()和detachEvent(),如
obj.attachEvent(‘onclick’,function(){})

  • 注意第一个参数”on”+xxx,事件处理程序是在全局作用域下运行,this等于window
  • 一个元素上的多个事件处理程序会以”相反的顺序”被触发。

Javascript中,添加到页面上的事件处理程序数量直接关系到页面的整体运行性能。对“事件处理程序过多”问题的解决方案就是事件委托

使用事件委托,只需在DOM树中尽量高的层次节点上添加一个事件处理程序,如
example
栗子中,虽然没有在每个li中添加事件,但通过在ul上添加事件监听,事件会沿着li>ul>body>html元素顺序依次发生,直到最终目标元素发生事件

适合采用事件委托技术的事件包括click、mousedown、mouseup、keydown、keyup、keypress

除了事件委托

在不需要的时候移除事件处理程序,清除内存中留有那些过时不用的“空事件处理程序”。

DOM0级: xxx.onclick=null;
DOM2级: xxx.removeEventListener(‘’,funName,false)
其中DOM2级中的removeEventListener()中传入的事件处理程序函数必须与addEventListener()相同(要调用外部函数而非匿名函数)

一个问题

example
这段代码中,倘若给每个元素事件处理程序属性上添加onclick=”alert(‘xxx’)”事件,点击最深层次的元素,就会连续alert出相应的东西。但点击嵌套层次中间的元素结点,不会连续打印出元素名。

答案一: 只绑定一次,应该每个子元素上都绑定click
答案二:……