什么是事件流,事件流指的是事件完整执行过程中的流动路径
事件流分为两种,第一是捕获(从大范围到小范围),第二是冒泡(从小范围到大范围)。
假设我们有四个标签,Document、html、body、div。
如果我们点击了div标签,执行过程时先经过了Document,然后经过html,再经过body,最后来到div,这一过程叫捕获(大范围到小范围)。
如果我们点击了Document,执行过程中先经过div,然后经过body,再经过html,最后来到Document,这一过程叫冒泡(小范围到大范围)。
我们使用如下代码(事件监听的第三个参数写上true):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#one{
width: 500px;
height: 500px;
background-color: red;
}
#two{
width: 300px;
height: 300px;
background-color: green;
}
#three{
width:100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="one">
<div id="two">
<div id="three">
</div>
</div>
</div>
<script>
document.querySelector('#one').addEventListener('click',function(){
alert('点击了爷爷')
},true)
document.querySelector('#two').addEventListener('click', function () {
alert('点击了爸爸')
}, true)
document.querySelector('#three').addEventListener('click', function () {
alert('点击了孙子')
}, true)
</script>
</body>
</html>
运行结果如下:
我们点击黄色盒子,会依次弹出点击了爷爷、点击了爸爸、点击了孙子,从大范围到小范围,这就是事件捕获。
我们再使用如下代码(删除事件监听的第三个参数):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#one{
width: 500px;
height: 500px;
background-color: red;
}
#two{
width: 300px;
height: 300px;
background-color: green;
}
#three{
width:100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="one">
<div id="two">
<div id="three">
</div>
</div>
</div>
<script>
document.querySelector('#one').addEventListener('click',function(){
alert('点击了爷爷')
})
document.querySelector('#two').addEventListener('click', function () {
alert('点击了爸爸')
})
document.querySelector('#three').addEventListener('click', function () {
alert('点击了孙子')
})
</script>
</body>
</html>
运行结果如下:
我们点击黄色盒子,会依次弹出点击了孙子、点击了爸爸、点击了爷爷,从大范围到小范围,这就是事件冒泡。
事件冒泡的概念:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程称为事件冒泡。
简单理解就是当一个元素被触发事件后,会依次向上调用所有父级元素的同名事件。
有些情况下我们不需要捕获和冒泡,该如何阻止呢?想要阻止事件捕获和事件冒泡需要拿到事件对象,然后使用语法:事件对象.stopPropagation()。例如我们在将最后一个事件监听的代码改成:
document.querySelector('#three').addEventListener('click', function (e) {
alert('点击了孙子')
e.stopPropagation()
})
再点击黄色盒子,仅弹出点击了孙子。