美文网首页我爱编程JS 深入了解系列
深入JS事件冒泡与事件代理(委托)

深入JS事件冒泡与事件代理(委托)

作者: 七_五 | 来源:发表于2018-05-22 19:58 被阅读0次

事件作为DOM操作中重要的一个点,好好的理解并运用相当的重要

1、事件冒泡

简单的说,就是当一个子元素的事件被触发的时候(如onclick事件),该事件会从事件源(被点击的子元素)开始逐级向上传播,触发父级元素的点击事件。

 <div id="parent" style="background-color: #000;height: 400px;width: 400px" data-id="11">  
    <div id="child" style="background-color: #fff;height: 200px;width: 200px" data-id="22"></div>  
 </div> 

document.getElementById('parent').onclick=function () {  
    console.log(this.getAttribute('data-id'));  
};  
document.getElementById('child').onclick=function (e) {  
    console.log(this.getAttribute('data-id'));  
};  

在线运行: http://jsbin.com/ritivosoco/edit?html,js,console,output

这里我们可以发现,当你点击白色区域(子元素),父级的click事件也被触发啦(观察控制台的输出),那么这里就有一个问题啦,可不可以当点击子元素的时候不触发父元素的点击事件啊,这就是接下来要说的啦

2、阻止事件冒泡

所谓阻止事件冒泡其实啊,就是我们不让点击这个事件传递给父元素啊,哈哈,这就要用到事件中的一个stopPropagation()方法啦,还是先看代码吧

document.getElementById('parent').onclick=function () {  
    console.log(this.getAttribute('data-id'));  
};  
document.getElementById('child').onclick=function (e) {  
    console.log(this.getAttribute('data-id'));  
    e.stopPropagation();  
};  

在线运行: http://jsbin.com/ritivosoco/edit?html,js,console,output

嘿嘿,此刻你在线上运行的时候是不是发现当我们点击白色区域的时候并没有触发到父元素的点击事件啊,这是因为我们阻止了子元素的事件冒泡啦!

朋友们有可能会觉得事件冒泡真是烦人,写个事件还要阻止冒泡!不过凡事都有双刃剑,事件冒泡同时给我们带来的还有事件委托这一减少DOM操作的神器,接下来介绍哦

3、事件委托

事件委托,首先按字面的意思就能看你出来,是将事件交由别人来执行,再联想到上面讲的事件冒泡,是不是想到了?对啦,其实就是将子元素的事件通过冒泡的形式交由父元素来执行。

可能在开发的时候会遇到这种情况:如导航每一个栏目都要加一个事件,你可能会通过遍历来给每个栏目添加事件,首先我们来看一段不使用事件委托的代码, 我们遍历子元素数组:

 <ul id="parent">  
   <li>孩子1</li>  
   <li>孩子2</li>  
   <li>孩子3</li>  
   <li>孩子4</li>  
   <li>孩子5</li>
 </ul>
 var ul = document.getElementById('parent')
 var lis = ul.getElementsByTagName('li')
 for (var i = 0; i<lis.length;i++){  
   lis[i].onclick= function() {  
     alert(this.innerHTML);  
   }
 }

这种方式看起来直接明了,但需要多次操作dom(每点击一个li都会操作一次dom),如果子元素较多的话则是一件相当恐怖的事情,而且当我们后面添加一个新的li子元素后,新添加的li没有绑定事件,需要再次给新的li绑定一次,考虑到给新添加的元素绑定事件:

<ul id="parent">  
   <li>孩子1</li>  
   <li>孩子2</li>  
   <li>孩子3</li>  
   <li>孩子4</li>  
   <li>孩子5</li>
 </ul>
 var ul = document.getElementById('parent')
 var lis = ul.getElementsByTagName('li')
 function addClick() {
   for (var i = 0; i<lis.length;i++){  
     lis[i].onclick= function() {  
       alert(this.innerHTML);  
     }
   }
}
addClick()

function addElement() {  
   var li = document.createElement('li');  
   li.innerHTML="我是新孩子";  
   ul.appendChild(li);  
   addClick();  
} 
addElement();  

上面写的代码确实可以解决新添加子元素的问题,但代码就有点多了,而且本质上并没有改变DOM的操作次数,优化性能,下面我们直接来看事件委托的写法:

<ul id="parent">
  <li>孩子1</li>  
  <li>孩子2</li>  
  <li>孩子3</li>  
  <li>孩子4</li>  
  <li>孩子5</li>
</ul>

var ul = document.getElementById('parent');  
ul.onclick = function (e) {  
  //判断只有li触发的才会输出内容  
  if(e.target.nodeName.toLowerCase() === "li"){
    alert(e.target.innerHTML);  
  }  
  e.stopPropagation();                          
}

在线运行: http://jsbin.com/bamonabeda/16/edit?html,js,console,output

因为是监听的父元素,所有即使新添加元素也是可以默认绑定好事件的,这样我们可以看到代码更简洁了,也减少了dom的操作次数,是不是非常的优雅和nice啊!

4、总结

最后总结下哈,事件冒泡是个双刃剑,当对我们有负面的影响的时候就显得相当讨厌,不过我们可以用阻止冒泡来达到我们想要的效果;但是在另一方面在特定的场合我们又可以借助于事件冒泡来优化我们的代码,优化性能,只有对原理了解于心,才可以突破更多的限制

相关文章

  • 深入JS事件冒泡与事件代理(委托)

    事件作为DOM操作中重要的一个点,好好的理解并运用相当的重要 1、事件冒泡 简单的说,就是当一个子元素的事件被触发...

  • js事件深入学习

    JavaScript的事件机制包含,事件绑定、事件监听、事件委托(事件代理)等 js中的事件流 ① .冒泡:当下级...

  • js 事件委托 事件代理

    js 事件委托 事件代理 JavaScript高级程序设计上解释:事件委托就是利用事件冒泡,只指定一个事件处理程序...

  • 事件委托

    还有很多要学,要加油哇。回正题。参考: js中的事件委托或是事件代理详解 1、基本概念事件委托就是利用事件冒泡,只...

  • 前端知识二

    事件委托(事件代理) 事件委托也可以叫事件代理,是事件冒泡与事件捕获的运用。 基本概念 一般来讲,会把一个或者一组...

  • JavaScript中的事件代理

    概念: JavaScript高级程序设计 (简称JS高程) :事件代理 (事件委托) 利用了事件冒泡,只指定一个事...

  • js事件委托

    前言 事件委托,也叫事件代理,是js事件中的一种常用技巧。事件委托的原理就是利用冒泡事件的机制,为一些节点的祖先节...

  • 事件委托

    概念 事件委托又叫事件代理,事件委托就是利用事件冒泡,只制定一个事件处理程序,就可以管理某一类型的所有事件。在js...

  • 什么是事件代理和事件委托

    昨天讲过了事件冒泡,其实事件代理和事件委托就是来源于事件冒泡机制。经常写js的人应该都知道这个方法。一个交互丰富的...

  • JS一步一步来说说事件委托(或者叫事件代理)

    一步一步来说说事件委托(或者有的资料叫事件代理) js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。 事...

网友评论

    本文标题:深入JS事件冒泡与事件代理(委托)

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