事件委托

129 阅读2分钟

概述:

什么叫事件委托呢?它还有一个名字叫事件代理,JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。 网上的大牛们讲事件委托基本上都用了同一个例子,就是取快递来解释这个现象。
例:一个宿舍的同学同时快递到了,一种方法就是他们一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个宿舍同学;

在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。

优点:

  1. 提高JavaScript性能。事件委托可以显著的提高事件的处理速度,减少内存的占用。
  2. 动态的添加DOM元素,不需要因为元素的改动而修改事件绑定。
基本实现:

1.JavaScript原生实现事件委托

    <ul id="myLinks">
      <li id="goSomewhere">Go somewhere</li>
      <li id="doSomething">Do something</li>
      <li id="sayHi">Say hi</li>
    </ul>

按照传统的做法,需要像下面这样为它们添加 3 个事 件处理程序:

    var item1 = document.getElementById("goSomewhere");
    var item2 = document.getElementById("doSomething");
    var item3 = document.getElementById("sayHi");
 
    item1.onclick = function() {
      location.href = "http://www.baidu.com";
    };
    item2.onclick = function() {
      document.title = "事件委托";
    };
    item3.onclick = function() {
      alert("hi");
    };

如果在一个复杂的 Web 应用程序中,对所有可单击的元素都采用这种方式,那么结果就会有数不 清的代码用于添加事件处理程序。此时,可以利用事件委托技术解决这个问题。使用事件委托,只需在 DOM 树中尽量最高的层次上添加一个事件处理程序,如下面的例子所示

    var item1 = document.getElementById("goSomewhere");
    var item2 = document.getElementById("doSomething");
    var item3 = document.getElementById("sayHi");
 
    document.addEventListener("click", function (event) {
      var target = event.target;
      switch (target.id) {
        case "doSomething":
          document.title = "事件委托";
          break;
        case "goSomewhere":
          location.href = "http://www.baidu.com";
          break;
        case "sayHi": alert("hi");
          break;
      }
    })

2.jQuery事件delegate()实现事件委托:

delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。

格式:$(selector).delegate(childSelector, event, data, function)

参数描述
childSelector必需,规定要附加事件处理程序的一个或多个子元素。
event 必需,规定附加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。
data可选,规定传递到函数的额外数据。
function必需,规定当事件发生时运行的函数。
<!DOCTYPE html>
<html>
 
<head>
  <meta charset="utf-8">
  <script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
 
<body>
  <ul id="myLinks">
    <li id="goSomewhere">Go somewhere</li>
    <li id="doSomething">Do something</li>
    <li id="sayHi">Say hi</li>
  </ul>
 
  <script>
    $(document).ready(function () {
      $("#myLinks").delegate("#goSomewhere", "click", function () {
        location.href = "http://www.baidu.com";
      });
    });
  </script>

</body>
</html>

使用事件委托注意事项:

使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。

参考资料 JavaScript事件代理