美文网首页
事件委托

事件委托

作者: 你喜欢吃青椒吗_c744 | 来源:发表于2019-08-06 15:25 被阅读0次

基本概念

事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素;

一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。

举个例子,比如一个宿舍的同学同时快递到了,一种方法就是他们都傻傻地一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一一分发给每个宿舍同学;

事件冒泡与捕获

image.png

为什么用事件委托

1:绑定事件越多,浏览器内存占用越大,严重影响性能。

2:ajax的出现,局部刷新的盛行,导致每次加载完,都要重新绑定事件

3:部分浏览器移除元素时,绑定的事件并没有被及时移除,导致的内存泄漏,严重影响性能

4:大部分ajax局部刷新的,只是显示的数据,而操作却是大部分相同的,重复绑定,会导致代码的耦合性过大,严重影响后期的维护。

事件委托影响性能的因素:

  • 元素中,绑定事件委托的次数
  • 点击的最底层元素,到绑定事件元素之间的DOM层数

什么时候选择使用事件委托

1:只在必须的地方,使用事件委托,比如:ajax的局部刷新区域

2:尽量的减少绑定的层级,不在body元素上,进行绑定

3:减少绑定的次数,如果可以,那么把多个事件的绑定,合并到一次事件委托中去,由这个事件委托的回调,来进行分发。

一个例子

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul id="ul-test">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
</ul>
</body>
<script type="text/javascript">
  var oUl=document.getElementById("ul-test");
  var oLi=oUl.getElementsByTagName("li");
  for(var i=0,len=oLi.length;i<len;i++){
    oLi[i].addEventListener("click",function(){
      alert(this.innerHTML)
    })
  }
</script>
</html>

问题在于:

  • for循环,循环的是li,10个li就循环10次,绑定10次事件,1000个就循环了1000次,绑定1000次事件!
  • 如果li不是本来就在页面上的,是未来元素,是页面加载了,再通过js动态加载进来了,上面的写法是无效的,点击li是没有反应的!应该怎么解决以上问题?

解决的办法就是通过事件委托

var oUl=document.getElementById("ul-test");
oUl.addEventListener("click",function(ev){
  console.log(ev)
  var ev=ev||window.event;// 兼容性处理
  var target=ev.target||ev.srcElement;
   // 获取到目标阶段指向的元素。如果点击的最底层是li元素
  if(target.tagName.toLowerCase()==='li'){
    alert(target.innerHTML)
  }
})

原理

事件的传播有三个阶段:
当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分成三个阶段:

  • 第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
  • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
  • 第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。

这种三阶段的传播模型,会使得一个事件在多个节点上触发。比如,假设点击<div>之中嵌套一个<p>节点。

<div>
  <p>Click Me</p>
</div>

如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。

  • 捕获阶段:事件从<div>向<p>传播时,触发<div>的click事件;
  • 目标阶段:事件从<div>到达<p>时,触发<p>的click事件;
  • 目标阶段:事件离开<p>时,触发<p>的click事件;
  • 冒泡阶段:事件从<p>传回<div>时,再次触发<div>的click事件。

注意,用户点击网页的时候,浏览器总是假定click事件的目标节点,就是点击位置的嵌套最深的那个节点(嵌套在<div>节点的<p>节点)。所以,<p>节点的捕获阶段和冒泡阶段,都会显示为target阶段。

事件传播的最上层对象是window,接着依次是documenthtml(document.documentElement)body(document.body)。也就是说,如果<body>元素中有一个<div>元素,点击该元素。事件的传播顺序,在捕获阶段依次为window、document、html、body、div,在冒泡阶段依次为div、body、html、document、window。

定义

由于事件会在冒泡阶段传向父节点,因此可以把子节点的监听函数绑定在父节点上,用父节点的监听函数统一处理多个子节点的事件,这就是事件代理。

var ul = document.querySelector('ul');

ul.addEventListener('click', function(event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code
  }
});

上面这个函数事件监听绑在ul身上,但是监听到点击li的事件,然后处理li点击后的回调。

就算li是动态添加进来的依然能够监听到。

总结

由于一个事件在传播的过程中有三个阶段,由最外层的父节点一层层传递到最里面的子节点,先是捕获阶段,到目标阶段,再到冒泡阶段。如果我们想监听到动态添加的子节点的事件,我们可以把事件绑在父节点上,利用event.target,筛选到子节点,处理事件相应的回调!!!

参考文章

JavaScript 事件委托详解

深入理解-事件委托

事件委托(事件代理)

相关文章

  • 事件委托

    ------------------事件委托----------------- 事件: 事件委托: 原理: 冒泡 ...

  • web前端面试题@六(事件委托)

    *说到事件委托,我们首先先要知道什么是事件委托—— · 那么什么是事件委托呢??? JS里的事件委托就是当事件...

  • 前端常见面试题(十一)@郝晨光

    什么是事件委托?为什么要用事件委托? 什么是事件委托? 事件委托,又称事件代理,就是将元素的事件处理交由父元素或者...

  • 十六、DOM之事件委托 ------ 2020-01-05

    1、事件委托: 2、事件委托的优势:

  • JQuery事件委托

    JavaScript(jQuery)中的事件委托 一:什么是事件委托? 事件委托是利用事件冒泡,只指定一个事件...

  • 事件委托笔记

    事件委托原理:事件冒泡机制。 什么是事件委托: 事件委托——给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪...

  • 事件委托

    事件委托 什么是事件委托(事件代理): 事件委托就是利用事件冒泡的原理,将事件注册到父元素上,减少子元素的事件注册...

  • JavaScript 事件委托

    1. 事件委托 事件处理程序过多的解决方法就是事件委托,事件委托利用的是事件冒泡。事件冒泡:事件由最具体的元素接收...

  • 原始类型与事情委托

    1.绑定事件: 二、事件冒泡与事件捕获 事件委托 案例见事件委托 计时器

  • 事件(二)

    一.事件委托# 事件委托就是利用事件冒泡的原理,把事件添加到父元素或祖先元素上,触发执行效果 事件委托优点1、提高...

网友评论

      本文标题:事件委托

      本文链接:https://www.haomeiwen.com/subject/yvsidctx.html