事件冒泡与事件捕获

事件冒泡:就是元素自身的事件被触发后,如果父元素有相同的事件,如onclick事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到document/window,冒泡过程结束。
<style type="text/css">
/*清除样式*/
*{margin: 0;padding: 0;}
ul li{list-style-type: none;}
a{text-decoration: none; color: inherit;}
/*---------------------------------------------------*/
.box1{
width: 300px;
height: 300px;
margin: 50px auto;
background: #000;
color: white;
}
.box2{
width: 200px;
height: 200px;
margin-top: 20px;
background: red;
}
.box3{
width: 100px;
height: 100px;
margin-top: 20px;
background: green;
}
</style>
</head>
<body style='height: 2500px;'>
<div class="box1">
box1
<div class="box2">
box2
<div class="box3">box3</div>
</div>
</div>
<script type="text/javascript">
var box1 = document.getElementsByClassName( 'box1' )[0],
box2 = document.getElementsByClassName( 'box2' )[0],
box3 = document.getElementsByClassName( 'box3' )[0];
addEvent( box1 , 'click' , fn);
addEvent( box2 , 'click' , fn2);
addEvent( box3 , 'click' , fn3);
function fn(){
console.log( 'box1' )
}
function fn2(){
console.log( 'box2' )
}
function fn3(){
console.log( 'box3' )
}
function addEvent( obj , type , eFn ) {
function fn(e , b){
e = e || window.event;
eFn.call( obj , e ) //处理this指向跟event问题
}
if( window.addEventListener ){
obj.addEventListener( type , fn ,false )
} else {
obj.attachEvent( 'on' + type , fn )
}
return fn; //把上面的fn函数return上面 上面用一个变量来接收 为了清除事件
}
</script>

阻止冒泡:阻止子元素事件向父元素冒泡
相当于在鱼吐泡的时候给它弄破就不会冒泡了
event.cancelBubble = true (不符合W3C)
event.stopPropagation() (符合W3C) 不兼容IE6 7 8
<style type="text/css">
/*清除样式*/
*{margin: 0;padding: 0;}
ul li{list-style-type: none;}
a{text-decoration: none; color: inherit;}
/*---------------------------------------------------*/
#box1{
width: 300px;
height: 300px;
margin: 50px auto;
background: #000;
color: white;
}
#box2{
width: 200px;
height: 200px;
margin-top: 20px;
background: red;
}
#box3{
width: 100px;
height: 100px;
margin-top: 20px;
background: green;
}
</style>
</head>
<body style='height: 2500px;'>
<div id="box1">
box1
<div id="box2">
box2
<div id="box3">box3</div>
</div>
</div>
<script type="text/javascript">
var box1 = document.getElementById( 'box1' ),
box2 = document.getElementById( 'box2' ),
box3 = document.getElementById( 'box3' );
addEvent( box1 , 'click' , fn);
addEvent( box2 , 'click' , fn2);
addEvent( box3 , 'click' , fn3);
function fn(){
console.log( 'box1' )
}
function fn2(){
console.log( 'box2' )
}
function fn3(e){
e = e || window.event;
e.cancelBubble = true;
console.log( 'box3' )
}
function addEvent( obj , type , eFn ) {
function fn(e , b){
e = e || window.event;
eFn.call( obj , e ) //处理this指向跟event问题
}
if( window.addEventListener ){
obj.addEventListener( type , fn ,false )
} else {
obj.attachEvent( 'on' + type , fn )
}
return fn; //把上面的fn函数return上面 上面用一个变量来接收 为了清除事件
}
</script>
</body>

第三个参数实例
<body style='height: 2500px;'>
<div id="box1">
box1
<div id="box2">
box2
<div id="box3">box3</div>
</div>
</div>
<script type="text/javascript">
var box1 = document.getElementById( 'box1' ),
box2 = document.getElementById( 'box2' ),
box3 = document.getElementById( 'box3' );
addEvent( box1 , 'click' , fn , false ); // 这里规定都是冒泡事件
addEvent( box2 , 'click' , fn2 , false ); //这里规定都是冒泡事件
addEvent( box3 , 'click' , fn3 , false ); //这里规定都是冒泡事件
//从子元素向父元素触发
function fn(){
console.log( 'box1' )
}
function fn2(){
console.log( 'box2' )
}
function fn3(e){
console.log( 'box3' )
}
function addEvent( obj , type , eFn ) {
function fn(e , b){
e = e || window.event;
eFn.call( obj , e ) //处理this指向跟event问题
}
if( window.addEventListener ){
obj.addEventListener( type , fn ,false )
} else {
obj.attachEvent( 'on' + type , fn )
}
return fn; //把上面的fn函数return上面 上面用一个变量来接收 为了清除事件
}
</script>
<body>

addEvent( box1 , 'click' , fn , false ); // 这里规定都是冒泡事件
addEvent( box2 , 'click' , fn2 , true); //这里规定都是捕获事件
addEvent( box3 , 'click' , fn3 , true); //这里规定都是捕获事件
点击box3的时候 box2是box3的父级 捕获是从父级执行下来, 先是box2触发 再执行box3
box2 和 box3 是box1的子元素 冒泡时父级是最后执行 最后是box1触发

addEvent( box1 , 'click' , fn , true); // 这里规定都是捕获事件
addEvent( box2 , 'click' , fn2 , true); //这里规定都是捕获事件
addEvent( box3 , 'click' , fn3 , true); //这里规定都是捕获事件
父级向子级传递

addEvent( box1 , 'click' , fn , true ); //规定是捕获
addEvent( box2 , 'click' , fn2 , false );//规定是冒泡
addEvent( box3 , 'click' , fn3 , false );//规定是冒泡
box3 跟 box2是box1的子元素 box1是捕获 所有捕获会从父级执行下来,box2跟box3是冒泡,冒泡是从子元素向父级的所有box3执行,最后是box2

如果捕获与冒泡事件同时存在的时候 捕获优先执行
事件源的捕获与冒泡事件共存时看输写顺序
<div class="box"></div>
<script type="text/javascript">
var oBox = document.getElementsByClassName( 'box' )[0];
oBox.addEventListener( 'click' , function (){
console.log( '捕获' );
} ,true)
oBox.addEventListener( 'click' , function (){
console.log( '冒泡' );
} ,false)
</script>

<div class="box"></div>
<script type="text/javascript">
var oBox = document.getElementsByClassName( 'box' )[0];
oBox.addEventListener( 'click' , function (){
console.log( '冒泡' );
} ,false)
oBox.addEventListener( 'click' , function (){
console.log( '捕获' );
} ,true)
</script>

网友评论