浏览器最初开始支持事件时,同一个事件仅仅只有一个元素相应。后来认为仅仅支持一个单一事件是不够的,而IE4之后提出了事件流的概念,一个元素可以支持多个事件。常见的事件流有捕捉型事件和冒泡型事件。
1、事件捕获
捕获型事件:事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)
2、事件冒泡
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
为了更好地体会,我们现在写一个demo,html 和 css 如下:
打开浏览器查看,效果如下:
接下来,我需要给它添加一些JS代码:
var d1 = document.getElementById("d1"); var d2 = document.getElementById("d2"); var d3 = document.getElementById("d3"); d1.addEventListener("click",function(){ this.style.background = "orange"; console.log(111); }) d2.addEventListener("click",function(){ this.style.background = "green"; console.log(222); }) d3.addEventListener("click",function(){ this.style.background = "blue"; console.log(333); })
现在,当我们点击最外层的圆d1时:
当我们点击中间的圆d2时:
当我们点击最里面的圆d3时:
【现象】:
在d1中点击时,打印结果为:111
在d2中点击时,打印结果为:222,111
在d3中点击时,打印顺序是:333,222,111
【结论】:事件的触发顺序自内向外,这就是事件冒泡。
这是因为,addEventListener("事件",函数,Boolean)第三个参数默认值为false,所以会有事件冒泡的发生。
true - 事件句柄在捕获阶段执行
false- 事件句柄在冒泡阶段执行
this和e.target的异同
现在,我们给刚刚的 圆形d1 添加两行JS代码:
然后我们按顺序分别点击圆 d1, d2, d3 , 看一下 this 和 event.target 在控制台上分别打印的结果:
【结论】:
js中事件是会冒泡的,所以this不一定是直接接受事件的目标DOM,
但event.target不会变化,它永远是直接接受事件的目标DOM元素;