js事件流程和事件阻止
js事件传播流程主要分三个阶段:
- 事件捕获阶段: 从外向里查找元素
- 处于目标阶段:从当前事件源本身的操作
- 事件冒泡阶段:从内到外依次触发相关的行为(最常用的就是冒泡阶段)
不是所有的事件都要经历这三个过程:
Netscape认为事件流应该是事件捕获;
ie认为事件流应该是事件冒泡, ie没有提供选择,事件只能在冒泡阶段捕获。ie认为事件流应该是事件冒泡;
w3c认为首先是事件捕获然后是事件冒泡。 在支持w3c的浏览器中,程序员可以通过设置addEventListener(type,handler,useCapture)中的userCapture值来决定元素是在冒泡阶段执行事件还是捕获阶段执行,默认为false,即冒泡阶段。
冒泡
- 概念:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
- 触发前提:由内向外的DOM对象上的事件名一样,才会触发事件冒泡
- 阻止事件冒泡:(兼容ie)
var evt=e||event;
if(evt.stopPropagation){
evt.stopPropagation();
}else{
evt.cancleBuble=true;
}
注:ie低版本只支持冒泡,不支持捕获。
阻止事件的冒泡
("#dv1").mousedown(function(event){ event.stopPropagation(); });
$("#dv1").mousedown(function(event){ return false; });
这两种方法有所区别,event.stopPropagation()只阻止事件冒泡,不足阻止事件本身,而return false;还阻止事件本身。
<!DOCTYPE html>
<html>
<head>
<title>事件冒泡</title>
</head>
<body>
<div id="box1">
animal
<h5 id="dv1">dog</h5><h5 id="dv2">cat</h5>
</div>
<script type="text/javascript">
var dv1=document.getElementById('dv1');
var dv2=document.getElementById('dv2');
box1.addEventListener('click',function(){
alert('hello');
},false);//点击animal弹出hello
dv1.addEventListener('click',function(){
alert('world');
})//点击dog弹出world,hello
</script>
</body>
</html>
事件捕获
<!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()的区别在哪儿呢
?
后者只会阻止冒泡或者是捕获。 但是前者除此之外还会阻止该元素的其他事件发生,但是后者就不会阻止其他事件的发生