js事件冒泡及阻止
事件冒泡及阻止
当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window,当然其传播的是事件,绑定的执行函数并不会传播,如果父级没有绑定事件函数,就算传递了事件,也不会有什么表现,但事件确实传递了。
事件冒泡的原因是事件源本身可能没有处理事件的能力,即处理事件的函数并未绑定在该事件源上。它本身并不能处理事件,所以需要将事件传播出去,从而能达到处理该事件的执行函数。
实例
当点击id为i3的<div>时,浏览器会依次弹出3 2 1,这就是事件冒泡,此正方形处于叶节点上,对其操作的事件会向上进行冒泡,直到根节点。
<!DOCTYPE html>
<html>
<head>
<title>JS事件冒泡及阻止</title>
</head>
<style type="text/css">
div{
display: flex;
justify-content: center;
align-items: center;
}
</style>
<body>
<div id="i1" style="height: 150px;width: 150px;background: red;">
<div id="i2" style="height: 100px;width: 100px;background: green;">
<div id="i3" style="height: 50px;width: 50px;background: blue;"></div>
</div>
</div>
</body>
<script type="text/javascript">
document.getElementById("i1").addEventListener('click',function(e) {
alert(1);
})
document.getElementById("i2").addEventListener('click',function(e) {
alert(2);
})
document.getElementById("i3").addEventListener('click',function(e) {
alert(3);
})
</script>
</html>
应用场景
例如我们有10个<li>标签,每个标签有一个uid作为判断用户点击的区别,使用冒泡就不需要为每个<li>绑定点击事件,可以称为事件委托
<!DOCTYPE html>
<html>
<head>
<title>JS事件冒泡及阻止</title>
</head>
<style type="text/css">
li{
cursor: pointer;
}
</style>
<body>
<ul id="u1">
<li uid="0">0</li>
<li uid="1">1</li>
<li uid="2">2</li>
<li uid="3">3</li>
<li uid="4">4</li>
<li uid="5">5</li>
<li uid="6">6</li>
<li uid="7">7</li>
<li uid="8">8</li>
<li uid="9">9</li>
</ul>
</body>
<script type="text/javascript">
document.getElementById("u1").addEventListener('click',function(e) {
alert(e.srcElement.getAttribute('uid'));
})
</script>
</html>
阻止冒泡
有时候我们并不希望事件冒泡而去执行上级节点绑定的事件,这时候就需要阻止事件的冒泡,w3c的方法是e.stopPropagation(),IE则是使用window.event.cancelBubble = true;。
<style> .box { height: 100px; background-color: #f40; } p { height: 60px; background-color: #008284; } .txt { background-color: lightcoral; padding: 10px; display: inline-block; margin: 20px; } </style> </head> <body> <div class="box"> <p> <span class="txt"> <button>点击</button> </span> </p> </div> <script> var div = document.querySelector('.box'); var p = document.querySelector('p'); var span = document.querySelector('.txt'); var btn = document.querySelector('button'); div.onclick = p.onclick = btn.onclick = function(e) { console.log(this.tagName); } // span的单击事件阻止事件冒泡 span.onclick = function(e) { // 阻止事件冒泡 e.stopPropagation(); console.log('span阻止了冒泡') } </script> </body>
效果图
![]()
点击外层div出现43行打印结果
点击span出现阻止冒泡
点击button会出现43行打印结果才是50行的打印
可以看出点击哪一行它都会有一个先后顺序的出现
阻止事件默认
<style>
span {
display: inline-block;
width: 40px;
height: 30px;
background-color: #ccc;
line-height: 30px;
text-align: center;
}
</style>
</head>
<body>
<div>
<p><a href="https://www.baidu.com">跳转</a></p>
<a href="javascript:;">百度</a>
</div>
<form action="https://www.baidu.com" method="post">
<button>点击</button>
<i>
<span>点击</span>
</i>
</form>
<script>
// 获取a标签
var oA = document.querySelector('a');
var btn = document.querySelector('button');
// 阻止浏览器的默认行为
oA.addEventListener('click', function(e) {
e.preventDefault();
console.log('不跳转');
})
btn.onclick = function() {
// DOM0中的处理方式
return false;
console.log('点击跳转');
}
</script>
注意
- 不是所有的事件都能冒泡。以下事件不冒泡:
blur、focus、load、unload。 - 事件解决方案方式在不同浏览器,可能是有所区别的,有些不支持捕获型方案,多数浏览器默认冒泡型方案。
- 阻止冒泡并不能阻止对象默认行为,例如
submit按钮被点击后会提交表单数据,需使用e.preventDefault();阻止默认行为,IE则是window.event.returnValue = false;



浙公网安备 33010602011771号