本文主要介绍了js中事件冒泡,事件捕获,事件代理。
一、事件传播
一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段:
- 捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件(addEventListener可以将第三个参数置为true用来响应捕获事件)
- 目标阶段:在目标节点上触发,称为“目标阶段”
- 冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;
绑定事件
时通过addEventListener
函数,它有三个参数,第三个参数若是true
,则表示采用事件捕获
,若是false
(默认),则表示采用事件冒泡
。
事件捕获:
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<style>
#div1{
background: yellow;
width: 300px;
height: 300px;
padding: 50px;
}
#div2{
background: red;
width: 200px;
height: 200px;
padding: 50px;
}
#div3{
background: green;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="div1">
div1
<div id="div2">
div2
<div id="div3">
div3
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function (){
var odiv1=document.getElementById("div1");
var odiv2=document.getElementById("div2");
var odiv3=document.getElementById("div3");
odiv1.addEventListener("click",function(){
console.log("div1");
},true);
odiv2.addEventListener("click",function(){
console.log("div2");
},true);
odiv3.addEventListener("click",function(){
console.log("div3");
},true);
}
</script>
</html>
点击div3
事件冒泡:
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<style>
#div1{
background: yellow;
width: 300px;
height: 300px;
padding: 50px;
}
#div2{
background: red;
width: 200px;
height: 200px;
padding: 50px;
}
#div3{
background: green;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="div1">
div1
<div id="div2">
div2
<div id="div3">
div3
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function (){
var odiv1=document.getElementById("div1");
var odiv2=document.getElementById("div2");
var odiv3=document.getElementById("div3");
odiv1.addEventListener("click",function(){
console.log("div1");
},false);
odiv2.addEventListener("click",function(){
console.log("div2");
},false);
odiv3.addEventListener("click",function(){
console.log("div3");
},false);
}
</script>
</html>
点击div3
:
二、事件委托(事件代理)
事件代理
(Event Delegation),又称之为事件委托
。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素
,让父元素担当事件监听的职务
。事件代理的原理是DOM元素的事件冒泡
。
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<style>
#div1{
background: yellow;
width: 300px;
height: 300px;
padding: 50px;
}
#div2{
background: red;
width: 200px;
height: 200px;
padding: 50px;
}
#div3{
background: green;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="div1">
div1
<div id="div2">
div2
<div id="div3">
div3
</div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload = function(){
var oUl = document.getElementById("div1");
oUl.onclick = function(ev){
var ev = ev || window.event;
// target表示在事件冒泡中触发事件的源元素,在IE中是srcElement
var target = ev.target || ev.srcElement;
console.log(target.getAttribute("id"));
}
}
</script>
</html>
三、如何阻止事件冒泡和事件捕获
w3c的方法是e.stopPropagation()
,IE则是使用e.cancelBubble = true