JavaScript中捕获和阻止捕获、冒泡和阻止冒泡的方法
冒泡事件
虽然我们只点击了button元素,但是,button外的third、second、first上的事件由内向外以此被触发,触发的顺序是由DOM树的下层到DOM树的最上面,故称为冒泡。
(说明:尽管这里我使用了DOM2级事件处理程序,并设置每个事件为冒泡阶段发生,但是即使使用DOM0级,得到的结果也是这样的,冒泡是默认的)
注意:现代所有的浏览器都支持事件冒泡,只是在实现上有一些差别。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>memory leak</title>
</head>
<body>
<div id="first">
<div id="second">
<button id="button">冒泡</button>
</div>
</div>
<iframe src="https://www.cnblogs.com/zhuzhenwei918/p/6139880.html" height="200px" width="50%" frameborder="0"></iframe>
<script>
var button = document.getElementById('button'),
second = document.getElementById('second'),
first = document.getElementById('first'),
body = document.body,
html = document.documentElement;
button.addEventListener('click', function () {
alert('button');
});
second.addEventListener('click', function () {
alert('second');
});
first.addEventListener('click', function () {
alert('first');
});
body.addEventListener('click', function () {
alert('body');
});
html.addEventListener('click', function () {
alert('html');
});
window.addEventListener('click', function () {
alert('window');
});
iframe.addEventListener('click',function(){
alert("iframe");
})
</script>
</body>
</html>
点击按钮:从 button -> div1 -> div2 -> body -> html -> window。 即最终可以冒泡到window上。
冒泡的终点是哪里
首先简单介绍一下
HTML <iframe>
标签
实例
标记一个内联框架:这里我们内联了某个博客
<iframe src="https://www.cnblogs.com/zhuzhenwei918/p/6139880.html"></iframe>
上面的例子即使是有iframe的话,也是不影响的,比如,我们把这个页面嵌入到另外一个页面中, 最终也是会冒泡到这个页面的window,即使是在iframe上添加一个click事件,也是不会冒泡到这个iframe上的,即事件的冒泡是相互独立的。
阻止事件冒泡
但是如果我们不希望事件冒泡呢?那么如何阻止事件冒泡?
实际上,事件的对象有一个stopPropagation()方法可以阻止事件冒泡,我们只需要把上个例子中button的事件处理程序修改如下:
document.getElementById("button").addEventListener("click",function(event){
alert("button");
event.stopPropagation();
},false);
这样,点击button后,只会弹出一个弹窗,显示button,再点一下弹窗就消失
事件捕获
事件捕获和事件冒泡是刚好相反的,事件捕获是指不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件。举例如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>bubble</title>
<style>
button{
background: red;
color:white;
}
#third{
width: 50px;
height: 50px;
border:thin solid red;
}
#second{
width: 100px;
height: 100px;
border:thin solid red;
}
#first{
width:200px;
height: 200px;
border:thin solid red;
}
</style>
</head>
<body>
<div id="first">
<div id="second" >
<div id="third" >
<button id="button">事件冒泡</button>
</div>
</div>
</div>
<script>
document.getElementById("button").addEventListener("click",function(){
alert("button");
},true);
document.getElementById("third").addEventListener("click",function(){
alert("third");
},true);
document.getElementById("second").addEventListener("click",function(){
alert("second");
},true);
document.getElementById("first").addEventListener("click",function(){
alert("first");
},true);
</script>
</body>
</html>
大家可以看到这个例子我只是把addEventListener()方法的第三个参数由前面例子的false修改为了true,也就是使用捕获方式获得button,那么结果如下: 我们可以看到最外层的事件先被触发,最后才是我们点击的button事件被触发,这便是事件捕获。
那么我们如何才能阻止事件的捕获呢?使用event.stopPropagation()方法吗?答案是否定的,虽然stopPropagation()方法既可以阻止事件冒泡,也可以阻止事件捕获,也可以阻止处于目标阶段。
但是我们可以使用DOM3级新增事件stopImmediatePropagation()方法来阻止事件捕获,另外此方法还可以阻止事件冒泡。应用如下:
document.getElementById("second").addEventListener("click",function(){
alert("second");
event.stopImmediatePropagation();
},true);
这样,就可以在id为second处阻止事件的捕获了。
那么 stopImmediatePropagation() 和 stopPropagation()的区别在哪儿呢?
后者只会阻止冒泡或者是捕获。 但是前者除此之外还会阻止该元素的其他事件发生,但是后者就不会阻止其他事件的发生。 例子点击这里
注意:尽管这是Netscape Navigator提出的事件流,但是现在所有的浏览器都支持这种事件流模型。但是由于老的浏览器不支持,所以很少有人使用事件捕获。
DOM事件流
DOM2级事件规定的时间流包括 三个阶段:
-
事件捕获阶段
-
处于目标阶段
-
事件冒泡阶段 注意:在DOM事件流中,实际的目标在捕获阶段不会接收到事件,下一个阶段是处于目标阶段,这时事件被触发,最后进入事件冒泡阶段。我们认为处于目标阶段是事件冒泡阶段的一部分。
第三部分:DOM事件流 DOM2级事件规定的时间流包括 三个阶段:
事件捕获阶段 处于目标阶段 事件冒泡阶段 注意:在DOM事件流中,实际的目标在捕获阶段不会接收到事件,下一个阶段是处于目标阶段,这时事件被触发,最后进入事件冒泡阶段。我们认为处于目标阶段是事件冒泡阶段的一部分。
上一篇: 前端开发面试常见问题之其他疑问
下一篇: 前端面试必备的关键知识点有哪些?
推荐阅读
-
气泡排序(超级详细)--升序",从小到大;另一种是 "降序",从大到小。该主题可抽象为 "按升序对 n 个数字排序 "的一般形式。 排序是一种重要的基本算法。排序的方法有很多种,但在本题中我们将使用冒泡排序法。 冒泡法的基本思想 冒泡法的基本思想是,每次比较相邻的两个数字时,较小的那个会被移到前面。如果有 5 个数字9,8,5,2,0,第一次将前两个数字 8 和 9 互换。第二次将第二个和第三个数字(9 和 5)对调......这样一共对调 4 次,得到 8-5-2-0-9 的顺序,可以看到:最大的数字 9 一直在 "下沉",成为最下面的一个数字,而小的数字 "上升" 最小的数字 "上升"。最小的数字 0 已经向上 "浮 "了一个位置。经过第一次比较(共 4 次比较和交换),得到了最大的数字 9。 然后进行第二趟比较,对剩下的前 4 个数字(8、5、2、0)进行新一轮比较,这样第二个最大的数字就 "沉到了底部"。同样,按照上述方法进行第二轮比较。经过 3 次比较和交换,我们得到了第二大数 8。 按照这个规律,我们可以推断出,比较 5 个数字需要 4 次旅行,才能将 5 个数字从小到大排列起来。在第一次旅行中,两个数字之间进行了 4 次比较,在第二次旅行中,进行了 3 次比较......在第四次旅行中,只进行了一次比较。 思路总结 总结:如果有 n 个数字,那么要进行 n-1 次比较。在第一次行程中进行 n-1 次比较,在第 i 次行程中进行 n-i 次比较。
-
JavaScript 的基本排序方法包括冒泡排序、选择排序和插入排序
-
JavaScript中可以使用的三种方法来阻止事件冒泡
-
区分click事件触发多次、事件冒泡和阻止冒泡,以及event.stopPropagation、event.preventDefault和return false的差异
-
阻止事件冒泡,阻止默认事件,event.stopPropagation和event.preventDefault,return false的区别-1.event.stopPropagation方法
-
JavaScript事件冒泡及阻止冒泡的方法
-
讲解如何使用JavaScript阻止事件冒泡和默认行为
-
阻止JavaScript事件冒泡传递:cancelBubble和stopPropagation的用法
-
浅谈jQuery 中的事件冒泡和阻止默认行为
-
JavaScript事件流与事件冒泡、阻止冒泡、事件捕获(一目了然)