zoukankan      html  css  js  c++  java
  • DOM 事件与事件委托

    DOM 事件与事件委托

    本文写于 2020 年 5 月 28 日

    先思考一个问题:我们如何给一百个 button 添加点击事件?

    遍历?

    那岂不是要添加一百个监听器?

    这就需要事件委托了。

    其实这根本不是一个很难的概念,看下去,本文并不长。

    1. 点击事件

    现在我们拥有三个元素,他们嵌套成为爷爷、爸爸、儿子:

    <div class='grandpa'>
      <div class='father'>
        <div class='son'></div>
      </div>
    </div>
    

    然后分别给他们仨添加不同的三个事件监听。

    因为事件冒泡,我们能知道他们都会执行,并且会按照一定顺序执行。

    但是不同浏览器的顺序是不一样的

    IE 认为应该调用 .son 的事件,网景认为应该调用 .grandpa

    后来 2002 年,W3C 发布了标准:

    • 先按照从外向内——事件捕获
    • 在按照从内向外——事件冒泡

    整个过程就是——有监听函数就调用,没有就跳过。

    开发者可以自己选择把最外层的事件,放在捕获阶段还是冒泡阶段。

    如何选择呢?其实就是我们最熟悉的addEventListener

    我们经常会用它去绑定事件,我们一般都只会传入两个参数。

    可实际上这个函数有 3 个参数

    我们可以在第三个参数,放置一个布尔值,例如:xxx.addEventListener('click', fn, bool)

    如果是true,则是捕获方式(从外向内);如果不写,或者是falsy值,则是冒泡(从内向外)

    顺序问题

    上面说了,先捕获后冒泡。

    那我同时给一个元素,先挂一个冒泡,再挂一个捕获——谁先触发?

    谁先写,谁先触发,因为他们是同级的

    可以取消吗?

    捕获不可以取消,但是冒泡可以取消。(有些事件不能取消,比如滚动事件)

    e.stopPropagation()中断冒泡。

    2. 事件委托

    回到我们刚开始的问题:我们如何给一百个 button 添加点击事件?

    肯定不是遍历。

    我们可以直接给父元素添加事件,例如:

    father.addEventListener('click', e => {
      console.log(e.target)
      console.log(e.currentTarget)
    })
    

    这里看到,我们传入了一个 e,这个 e 可以尝试打印出来,就会发现其实是MouseEvent

    这是一个对象,里面有各种各样的数据,比如我们需要的target

    target就是用户所点击的元素!

    也就是说如果 father 有 10 个孩子,从 child1 一直到 child10,我们点谁,这个 target 就是谁

    e.currentTarget呢,和e.target是有区别的!

    简单来说呢 target被操作的元素currentTarget被监听的元素

    在这个例子中,currentTarget 恒为 father,target 则会随着点击发生改变。

    最后说一下,JS 其实是不支持事件的!支持事件的是浏览器,addEventListener 是浏览器的 DOM 提供的。

    (完)

  • 相关阅读:
    MySQL基础(一)
    创建SSM项目所需
    设计模式(三十)------23种设计模式(22):装饰器模式
    设计模式(三十一)------23种设计模式(23):简单工厂模式
    设计模式(三十二)------设计模式总结分类
    设计模式(二十八)------23种设计模式(20):外观模式
    设计模式(二十九)------23种设计模式(21):代理模式
    设计模式(二十七)------23种设计模式(19):组合模式
    算法与数据结构基础(四)高级排序算法2.快速排序
    设计模式(二十六)------23种设计模式(18):桥接模式
  • 原文地址:https://www.cnblogs.com/xhyccc/p/13442195.html
Copyright © 2011-2022 走看看