1. 事件阶段
参考文章
https://segmentfault.com/a/1190000012729080
W3C的DOM事件流包含三个阶段
事件捕获
目标阶段
事件冒泡
IE事件流,不支持事件捕获
- 处于相应阶段内的元素,响应事件就是按照事件的注册顺序来进行相应阶段的触发,比如都是捕获阶段的多个处理函数,就会依照注册顺序执行
- stopImmediatePropagation会阻止事件的传播,也会阻止在其执行之后注册的事件的执行
- 由第一点理解,在目标阶段,元素的事件是按照注册的顺序执行的,此时没有冒泡和捕获的区别,都是顺序执行事件处理函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#dv1 {
width: 300px;
height: 300px;
background-color: pink;
}
#dv2 {
width: 250px;
height: 250px;
background-color: red;
}
#dv3 {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="dv1">
<div id="dv2">
<div id="dv3"></div>
</div>
</div>
<script src="common.js"></script>
<script>
// 事件阶段:
// 1---捕获阶段-----从外向里
// 2---目标阶段-----最开始被选择的那个
// 3---冒泡阶段-----从里向外
// DOM2级事件,规定事件流有上述三个阶段,首先发生事件捕获,从document这个不太具体的节点开始接收事件
// 向内找到最具体的节点,就是目标,然后目标接收事件
// 最后再向外向document冒泡
// https://segmentfault.com/a/1190000012729080
// function f1() {
// console.log("dv1");
// }
// function f2() {
// console.log("dv2");
// }
// function f3() {
// console.log("dv3");
// }
//
// my$("dv1").addEventListener("click", f1, false);
// my$("dv1").addEventListener("click", f1, true);
// my$("dv2").addEventListener("click", f2, false);
// my$("dv2").addEventListener("click", f2, true);
// my$("dv3").addEventListener("click", f3, false);
// my$("dv3").addEventListener("click", f3, true);
var a = my$("dv1");
var b = my$("dv2");
var c = my$("dv3");
c.addEventListener("click", function (event) {
console.log("c1"+"----------"+event.eventPhase);
// 注意第三个参数没有传进 false , 因为默认传进来的是 false
//,代表冒泡阶段调用,个人认为处于目标阶段也会调用的
});
c.addEventListener("click", function (event) {
console.log("c2"+"----------"+event.eventPhase);
}, true);
b.addEventListener("click", function (event) {
console.log("b"+"----------"+event.eventPhase);
}, true);
a.addEventListener("click", function (event) {
console.log("a1"+"----------"+event.eventPhase);
}, true);
a.addEventListener("click", function (event) {
console.log("a2"+"----------"+event.eventPhase)
});
a.addEventListener("click", function (event) {
console.log("a3"+"----------"+event.eventPhase);
// event.stopImmediatePropagation();
}, true);
a.addEventListener("click", function (event) {
console.log("a4"+"----------"+event.eventPhase);
}, true);
</script>
</body>
</html>
2. 阻止事件冒泡
IE8 attachEvent/detachEvent—>火狐不支持,谷歌支持
标准:addEventListener/removeEventListener()三个参数,最后一个,false时,冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
/**
* 相同点:都可以为元素绑定事件
* 不同点:
* 1. 方法名不同
* 2. 参数数不同,对象.addEventListener(type, fn ,false),对象.attachEvent(type, fn);
* 3. 浏览器支持不同,第一个火狐 谷歌 IE11 OK IE8不OK 第二个 IE8ok 谷歌火狐IE11不OK
* 4. 事件类型,一个加on,一个不加on
* 5. this,对象.addEventListener,是当前绑定事件的对象
* 对象.attachEvent,是window
*
*/
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#dv1 {
width: 300px;
height: 300px;
background-color: pink;
}
#dv2 {
width: 250px;
height: 250px;
background-color: red;
}
#dv3 {
width: 200px;
height: 200px;
background-color: blue;
}
</style>
</head>
<body>
<div id="dv1">
<div id="dv2">
<div id="dv3"></div>
</div>
</div>
<script src="common.js"></script>
<script>
// 事件冒泡:当多个标签嵌套,然后都注册了相同的事件,那么里面的标签事件触发的时候,外面的也会触发
// window.event.cancelBubble = true;------->IE8特有的,谷歌可以,火狐不可以,
// IE8的事件处理参数对象是window.event--->用的是属性
// e.stopPropagation();----->火狐谷歌可以,IE8不可以,这是火狐的事件处理参数对象--->用的是方法
my$("dv1").onclick=function(){
console.log("dv1");
};
// 事件处理参数对象,IE8没有
my$("dv2").onclick=function(e){
console.log("dv2");
// window.event.cancelBubble = true;
console.log(e);
e.stopPropagation();
};
my$("dv3").onclick=function(e){
console.log("dv3");
e.stopPropagation();
};
</script>
</body>
</html>