Javascript中的事件冒泡与事件捕获

定义

事件冒泡和捕获分别由微软公司和网景公司提出,都是用来解决页面中事件流的问题,也就是解决事件发生顺序的问题。
举个例子:

如果我在a2上挂载一个click的处理函数,并在页面点击a2,那么是a1还是a2上注册的事件先被触发呢?

事件冒泡

微软公司的IE提出了事件冒泡的事件流。事件冒泡是什么意思呢?我们可以将其比喻为一个在水底的气泡,这个气泡在水里会不断往上升,直到浮出水面。事件冒泡就是类似这样一个从底往上的过程,事件会从最内层的元素开始发生,发生顺序一直向上,直到document。
也就是说,假设我们在前面的例子点击a2,那么事件发生的顺序为:
p -> div -> body -> html -> document

事件捕获

而网景公司提出的是事件捕获的事件流。如果说事件冒泡像从水底升上去的一个气泡,那么事件捕获则像是一块扔进水底的大石头。与事件冒泡相反,事件捕获的顺序是从最外层到最里层的元素:
document -> html -> body -> div -> p

addEventListener

mdn上的说明:
EventTarget.addEventListener(event, function, useCapture)方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。
这个方法输入三个参数。
第一个参数是要挂载的事件,比如click;
第二个参数输入的是发生事件对应的函数,如将div变色;
第三个参数输入的是一个布尔类型,当输入为false时,则处理事件按照事件冒泡顺序;若输入为true,则处理事件按照事件捕获顺序。第三个参数的默认值为false。

false ——> 事件冒泡(默认)
true ——> 事件捕获

事件冒泡例子

a1

a2

结果:
点击a1时,控制台出现a1 冒泡;点击a2时,控制台出现a2 冒泡 a1冒泡

事件捕获例子

a1

a2

结果:
点击a1时,控制台出现a1 捕获;点击a2时,控制台出现a1 捕获 a2捕获

同时有事件冒泡和事件捕获

我们先看看例子和执行结果:

a1
a2

结果:
点击a1,控制台出现a1 冒泡 a2 捕获
点击a2,控制台先后出现a1 捕获 a2 冒泡 a2 捕获 a1 冒泡

根据结果我们可以得出过程

1.从document开始往被点击的节点捕获前进,遇到注册的捕获事件就立刻执行该事件
2.到达被点击的节点后执行注册的事件
3.执行完被点击的节点上的事件后,冒泡前进,遇到注册的冒泡事件就立刻执行该事件

总结

1.对于非点击的节点来讲,先执行捕获再执行冒泡
2.对于被点击的节点来讲,则是按照顺序执行先注册的事件

实际应用:事件代理

利用这个事件流的特性,我们可以使用事件代理这种方法。

  • red
  • orange
  • yellow
  • green
  • blue
  • purple

假设要我们点击页面中的li元素,然后输出对应的颜色,我们可能会用循环来解决,但使用循环的缺点是每次循环都会创建一个新的函数来绑定事件,这样的性能损耗比较大。而如果使用事件代理方法,利用事件流的特征,我们只绑定一个事件处理函数也可以完成:

    color.addEventListener("click",(e)=>{
    let a = e.target
    if(a.nodeName === li){
        console.log("The color is" + a.innerHTML)
    }
    },false)

你可能感兴趣的:(Javascript中的事件冒泡与事件捕获)