Web前端之路

JavaScript事件委托机制

2019-07-30  本文已影响11人  jaimor

概念

事件委托是依靠事件冒泡,只需要指定一个事件处理程序,绑定一次就可以处理一类的事件。举个例子:假如有一个旅游团,其组成有旅游团公司 导游 旅行者。旅游团公司想征求下旅行者是否愿意更改路线,这里就有两种方式了。第一种:旅游团公司直接和每个旅行者建立联系,询问是否愿意更改路线。第二种:旅游团公司直接和导游取得联系,又导游来反馈给旅游团公司。其实第一种就是和每一个节点建立联系,最直接,但是也是比较耗费资源的,第二种就是事件委托机制了,把联系委托给导游,最终旅游者的意见会反馈到导游那里,然后旅游团公司再在导游那里做出反应。

优点

减少资源消耗。因为每次绑定一个事件是需要消耗系统资源的,内存啊之类的。
减少dom操作,就可以减少页面的重绘和结构重排,提升流畅性。

实例

<!-- 第一种比较简单的 -->
<div id="公司">
  <ul id="导游">
    <li>123</li>
    <li>345</li>
    <li>567</li>
  </ul>
</div>
var ul = document.getElementById("导游");
ul.addEventListener("click", function (event) {
  event.target.style.color = "red";
  console.log(event.target);
})
//<li>345</li> 等
<!-- 第二种,假如以下这种结构,我还是想将li的事件委托给ul来处理,怎么办? -->
<div id="公司">
  <ul id="导游">
    <li>123</li>
    <li>345</li>
    <li><span>xx</span></li>
    <li><span>xx <i>yy</i></span></li>
  </ul>
</div>
//如果还是用之前的方法
var ul = document.getElementById("导游");
ul.addEventListener("click", function (event) {
  event.target.style.color = "red";
  console.log(event.target);
})
//则必然会出现
//<span>xx <i>yy</i></span>  这里触发就没有在li上了

//这里我的解决方案就是使用event下的另外一个属性,path,这个属性记录了从根元素到event.target目标元素的触发过程堆栈。
var ul2 = document.getElementById("导游");
  ul2.addEventListener("click", function (event) {
    var max = event.path.indexOf(event.currentTarget);
    for (var i = max; i >= 0; i--) {   //这里就在寻找 委托目标 和 实际触发的目标之间 是否存在 li 元素,找到就表示存在,就执行相应的动作即可
      if (event.path[i].nodeName.toLowerCase() === 'li') {
        event.path[i].style.color = "red";
        console.log(event.path[i])
      }
    }
  })
上一篇 下一篇

猜你喜欢

热点阅读