饥人谷技术博客

从onClick谈事件代理和了解事件传播机制

2017-09-14  本文已影响77人  YM雨蒙

javasriptdelegate这个词经常出现,看字面的意思,代理、委托。

要搞懂事件代理,我们先来看看什么是代理,相信我们生活中现在还有朋友在做微商的,而微商的产品就是一级一级代理,下家找上家拿货这样子,你卖了东西从上家拿货,这个过程相当于你也有了货

我们怎么从字面上来了解事件的代理呢?慢慢来,我们先来看一个需求,有这样一个列表,当我们每次点击的时候,就在控制台打印列表里的内容

作为一名新手,我经常这样绑定onclick事件

我会循环每一个li当我点击一个在控制台显示打印结果,全部绑定click事件,于是,我的代码是这样的

 <ul class="ct">
    <li>我是一号</li>
    <li>我是二号</li>
    <li>我是三号</li>
    <li>我是四号</li>
    <li>我是五号</li>
  </ul>
  <button type = "button" id="btn">增加</button>

var ul = document.querySelector(".ct")
for(var i=0;i<ul.children.length;i++){
  ul.children[i].onclick = function(){
    console.log(this.innerText)
  } 
}
代码没有问题

我觉得这样写的挺好的,可是有人说这样会耗费性能,那我就不管了,可是当我改了一下需求,我发现这个代码用的没那么舒服了

我在代码中通过js加入新的li,当我点击新的li时,控制台没有打印我的代码?怎么回事?

我加入了几这样的代码

var btn =document.querySelector("#btn")
var i =6
btn.addEventListener("click",function(){
  var node = document.createElement("li")
  node.innerText = "我是" + i++ + "号"
  ul.appendChild(node)
})
后面增加的li没有在控制台打印

这是为什么?因为原有的li跟我后面生成的li根本不是同时发生的,在创建新的li元素之前,已经给存在的li加事件了,好吧,那我怎么修改呢?难道要重新循环遍历,太麻烦了,

有人告诉我可以用代理,代理是什么,看了文章,好吧,修改一下代码

ul.addEventListener("click",function(e){
 // 检查事件源e.targe是否为Li
  if(e.target.nodeName.toLowerCase() == 'li'){
    console.log(e.target.innerText)
  }
})
成功了
新增新的点击li也会再控制台打印,解决了,于是耐心翻资料看了一下什么是事件代理:

定义:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

那什么是冒泡呢?

回到我们本文的这个例子,看看改动后的代码,我把onlick事件绑定到了ul标签上面,而不是li标签。于是,当我点击任何一个li标签(不管是动态生成的还是之前就有的)是,这个事件就开始冒泡,寻找父元素。由于我这里给ul绑定了onlick,那么这时,ul会捕获冒泡上来的onclick事件。

接着,如果,这个target刚刚好就是li标if(target.nodeName.toLowerCase() == 'li'),那么执行函数。

简单介绍一下事件传播机制,主要介绍DOM2.0

事件传播
上一篇下一篇

猜你喜欢

热点阅读