事件委托

2019/02/23 JavaScript views

概念


事件委托就是利用事件冒泡,只制定一个事件处理程序,就可以管理某一类型的所有事件。事件委托还有一个名字叫事件代理。

使用场景


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

如果需要给每个 li 绑定一个点击事件,点击时打印对应的序号,我们可以给每一个 li 都绑定一个事件,简单粗暴。但是如果 li 的数量很多,每一个 li 都绑定一个事件会增加更多的 DOM 操作,严重影响页面的性能。

还有一个问题,如果初始化时每一个 li 都是动态生成的,在绑定点击事件时会找不到对应的节点导致绑定失败,后续动态新添加的 li 也无法绑定事件。

这时我们就可以用到事件委托,将 li 的点击事件委托给它的父元素 ul,只需要给父元素绑定一个点击事件就可以实现多个子元素的点击事件。

window.onload = function() {
  var oUl = document.getElementById("ul");
  oUl.onclick = function(e) {
    var e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target.innerHTML);
  }
}

事件委托的核心是通过 event.target(当前事件元素).nodeName(dom元素的标签名) 取到标签,然后用类似 event.target.style.xxx 的操作来处理 DOM。

事件委托的原理


我们知道,DOM 事件流包括三个阶段:捕获阶段,目标阶段,冒泡阶段。

  • 事件捕获:当一个事件触发后,从 window 对象触发,不断经过下级节点,直到目标节点。在事件到达目标节点之前的过程就是捕获阶段。所有经过的节点,都会触发对应的事件。即 window -> document -> body -> div

  • 事件目标:当到达目标节点之后,执行对应的事件。

  • 事件冒泡:当事件到达目标节点后,会沿着捕获阶段的路线原路返回。同样,所有经过的节点,都会触发对应的事件。即 div -> body -> document -> window

事件委托是利用事件的冒泡原理来实现的。用父级 ul 做事件处理,当 li 被点击时,由于冒泡原理,事件就会冒泡到 ul 上,因为 ul 上有点击事件,所以事件就会被触发。

注意:由于事件委托是通过事件冒泡实现的,所以如果子元素阻止了事件冒泡,那么事件委托也将失效。

事件委托的优点


  • 提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。

  • 动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。

jQuery 中的事件委托


  • .bind()
  • .live()
  • .delegate()
  • .on()

前三种各有弊端,推荐使用第四种。

Search

    欢迎关注我的微信公众号

    闷骚的程序员

    Table of Contents