事件处理模型——事件冒泡、捕获
-
事件冒泡
-
- 结构上(非视觉上)向前关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
-
-
事件捕获
-
- 结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
-
- 触发顺序,先捕获,后冒泡
- focus,blur,change,submit,reset,select等事件不冒泡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>abraham</title>
<style>
.wrapper{
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height: 200px;
background-color: green;
}
.box{
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="content">
<div class="box"></div>
</div>
</div>
<script type="text/javascript">
var wrapper = document.getElementsByClassName("wrapper")[0];
var content = document.getElementsByClassName("content")[0];
var box = document.getElementsByClassName("box")[0];
wrapper.addEventListener("click",function(){
console.log("wrapper");
},false);
content.addEventListener("click",function(){
console.log("content");
},false);
box.addEventListener("click",function(){
console.log("box");
},false);
</script>
</body>
</html>
当我们点击红色的方块的时候,会显示wrapper,如图:
当我们点击绿色方块的时候,会显示content和wrapper,如图:
当我们点击橙色方块的时候,会显示box,content,wrapper,如图:
也就是说他们三个执行的事件是漏下去的,点击橙色方块的时候,橙色区域也算是绿色绿色区域了,所以绿色区域也触发了,然后红色的也触发了,紧接着一系列的慢慢的往下漏,我们称着样的现象叫做事件冒泡。但是我们总感觉这是慢慢往里面渗啊,不是冒泡啊!不能这样理解,咱们看一下定义:结构上(非视觉上)向前关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)
结构上存在父子关系的元素三个div,事件触发的顺序是这样的:如果你事件点击到了子元素上,他会一级一级的向他父元素上传递这个事件,所以这个从代码的视觉上来讲是自底向上。
事件冒泡模型是一种常规模型,还有一种不常规的是事件捕获模型。
事件捕获只有一种浏览器上好使,那就是谷歌(和最新版本的火狐等等),在触发之前,先清楚一点:一个对象的一个事件类型只能遵循一种事件模型。
怎么来触发事件捕获呢?
把addEventListener的false变成true,立马变成事件捕获模型。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>abraham</title>
<style>
.wrapper{
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height: 200px;
background-color: green;
}
.box{
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="content">
<div class="box"></div>
</div>
</div>
<script type="text/javascript">
var wrapper = document.getElementsByClassName("wrapper")[0];
var content = document.getElementsByClassName("content")[0];
var box = document.getElementsByClassName("box")[0];
wrapper.addEventListener("click",function(){
console.log("wrapper");
},true);
content.addEventListener("click",function(){
console.log("content");
},true);
box.addEventListener("click",function(){
console.log("box");
},true);
</script>
</body>
</html>
当我点击红色区域的时候,显示的是wrapper:
当我点击绿色区域的时候,显示的是wrapper和content:
当我点击橙色区域的时候,显示的是wrapper,content和box:
但是你得注意一点:当你点击橙色区域的时候,红色部分捕获事件并且执行,绿色部分捕获并且执行,橙色的部分就不是不活了,点击的就是人家,所以叫做事件执行。
同一个对象的同一个事件类型,上面绑定了两个事件处理函数,一个是使事件冒泡,一个叫事件捕获模型,那这两个的执行顺序就是先捕获,后冒泡!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>abraham</title>
<style>
.wrapper{
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height: 200px;
background-color: green;
}
.box{
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="content">
<div class="box"></div>
</div>
</div>
<script type="text/javascript">
var wrapper = document.getElementsByClassName("wrapper")[0];
var content = document.getElementsByClassName("content")[0];
var box = document.getElementsByClassName("box")[0];
wrapper.addEventListener("click",function(){
console.log("wrapper");
},true);
content.addEventListener("click",function(){
console.log("content");
},true);
box.addEventListener("click",function(){
console.log("box");
},true);
wrapper.addEventListener("click",function(){
console.log("wrapperBubble");
},false);
content.addEventListener("click",function(){
console.log("contentBubble");
},false);
box.addEventListener("click",function(){
console.log("boxBubble");
},false);
</script>
</body>
</html>
先捕获,后冒泡!
然后再换个绑定的顺序试试:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>abraham</title>
<style>
.wrapper{
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height: 200px;
background-color: green;
}
.box{
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="content">
<div class="box"></div>
</div>
</div>
<script type="text/javascript">
var wrapper = document.getElementsByClassName("wrapper")[0];
var content = document.getElementsByClassName("content")[0];
var box = document.getElementsByClassName("box")[0];
wrapper.addEventListener("click",function(){
console.log("wrapperBubble");
},false);
content.addEventListener("click",function(){
console.log("contentBubble");
},false);
box.addEventListener("click",function(){
console.log("boxBubble");
},false);
wrapper.addEventListener("click",function(){
console.log("wrapper");
},true);
content.addEventListener("click",function(){
console.log("content");
},true);
box.addEventListener("click",function(){
console.log("box");
},true);
</script>
</body>
</html>
wrapper是捕获的,content是捕获的,后面两个也是冒泡正常的,但是boxBubble和box是怎么回事?
顺序一定是先捕获后冒泡,这没有问题,但是当我点击橙色部分的时候,先捕获红色区域,再捕获绿色部分,然后叫做橙色部分的事件执行,再由橙色部分的事件执行冒泡到绿色部分,冒泡到红色部分,橙色部分是两个事件执行,事件执行的顺序是谁先绑定的谁先执行!