事件冒泡与事件捕获

JavaScript与HTML之间的交互是通过事件来实现的,事件就是当文档或者浏览器窗口发生一些特定的交互瞬间,事件流是指从页面中接收事件的顺序。IE和Netscape开发团队提出,当你点击页面上的按钮时,你也同时点击了按钮的容器元素,甚至也点击了整个页面,但是,对于事件流,这两个团队提出了两个完全相反的事件流概念,IE认为,事件流是冒泡流,而Netscape认为事件流是捕获流。

事件冒泡

事件冒泡即由最具体的元素(文档中嵌套层次最深的节点)到最不具体的元素(文档)。
HTML结构如下

JS代码

// DOM0级

child.onclick=function(){
    console.log('child')
}
parent.onclick=function(){
    console.log('parent')
}
document.onclick=function(){
    console.log('body')
}
document.onclick=function(){
    console.log('document')
}

// DOM2级

child.addEventListener('click',function(e){
    console.log('child');
},false)
parent.addEventListener('click',function(e){
    console.log('parent');
},false)
document.body.addEventListener('click',function(e){
    console.log('body');
},false)
document.addEventListener('click',function(e){
    console.log('document');
},false)
    

当点击child时,可以看到控制台

事件冒泡与事件捕获_第1张图片
image.png

当点击parent时


事件冒泡与事件捕获_第2张图片
点击parent

当点击body时

事件冒泡与事件捕获_第3张图片
点击body

当点击document时

点击document

也就是说,click事件首先在child元素上发生,然后沿DOM树向上传播,在parent元素上发生,最后传播到document上。如果只点击parent,就从parent沿着DOM树向上传播,直到document。

事件冒泡与事件捕获_第4张图片
冒泡过程

事件捕获

事件捕获是不太具体的节点应该最早接收事件,而最具体的节点最后接收事件。

// DOM2级
child.addEventListener('click',function(e){
    console.log('child');
},true)
parent.addEventListener('click',function(e){
    console.log('parent');
},true)
document.body.addEventListener('click',function(e){
    console.log('body');
},true)
document.addEventListener('click',function(e){
    console.log('document');
},true)

当点击child时


事件冒泡与事件捕获_第5张图片
点击child

当点击parent时


事件冒泡与事件捕获_第6张图片
点击parent

当点击body时


点击body

当点击document时

点击document

在事件捕获的过程中,click事件首先在document上发生,然后沿DOM树向下传播,最后传播到child上。如果只点击parent,就从document沿着DOM树向下传播,直到自己被点击。

事件冒泡与事件捕获_第7张图片
捕获过程

可以根据addEventListener()接收的第三个参数来规定是否选择事件冒泡或者事件捕获,true表示遵循事件捕获,false或者不传入参数表示遵循事件冒泡,建议使用事件冒泡,特殊情况下再使用事件捕获。

DOM2事件流

DOM2事件流包含了三个阶段:事件冒泡阶段,处于目标阶段,事件捕获阶段,首先发生的是事件捕获,为截获事件提供了机会,然后是事件的目标阶段接收阶段,最后一个阶段是冒泡阶段,可以在这个阶段对事件作出相应,如图


事件冒泡与事件捕获_第8张图片

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