js 事件流,事件冒泡機制
事件冒泡:當一個元素接收到事件的時候,會把他接收到的所有傳播給他的父級,一直到頂層window,
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<style>
div{padding: 40px;}
#div1{background: red;}
#div2{background: gold;}
#div3{background: firebrick;}
</style>
<script>
window.onload = function(){
var oDiv1=document.getElementById('div1');
var oDiv2=document.getElementById('div2');
var oDiv3=document.getElementById('div3');
function fn1(){
alert(this.id);
}
oDiv1.onclick = fn1;
oDiv2.onclick = fn1;
oDiv3.onclick = fn1;
}
</script>
</head>
<body>
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
</body>
</html>
三個div層層巢狀,當我只點選div3時,div3,div2.div1都彈出來了,這就是事件冒泡
如果把div3的點選事件取消,div2,div1仍然能夠彈出。
下拉選單:
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<style>
#div1{
width: 100px;
height: 200px;
border: 1px solid red;
display: none;}
</style>
<script type="text/javascript">
window.onload= function(){
var oBtn = document.getElementById('btn');
var oDiv = document.getElementById('div1');
//出現事件冒泡,不能得到預期效果
oBtn.onclick = function(){
oDiv.style.display = 'block';
}
document.onclick = function(){
oDiv.style.display = 'none';
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="按鈕" />
<div id="div1">
</div>
</body>
</html>
按鈕點選也不顯示div1
下面程式碼加了定時器,延遲了事件冒泡,
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<style>
#div1{
width: 100px;
height: 200px;
border: 1px solid red;
display: none;}
</style>
<script type="text/javascript">
window.onload= function(){
var oBtn = document.getElementById('btn');
var oDiv = document.getElementById('div1');
oBtn.onclick = function(){
oDiv.style.display = 'block';
}
document.onclick = function(){
setTimeout(function(){
oDiv.style.display = 'none';
},1000);
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="按鈕" />
<div id="div1">
</div>
</body>
</html>
過1s後紅方塊消失
思考:為什麼會有事件冒泡呢?這麼不好用的東西,直接去掉不行嗎?
如果沒有事件冒泡,想想如果想實現點選頁面上的任何一個元素都可以把方塊隱藏掉,是不是要獲取頁面總成千上萬個元素,然後進行隱藏的處理,才能實現,如果有冒泡,只需要給共同的父級document加點選事件處理,當你點選頁面中任何一個元素,他就會傳到他的父級,完成隱藏操作。
阻止冒泡:當前要阻止冒泡的事件函式中呼叫event.cancelBubble = true;
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<style>
#div1{
width: 100px;
height: 200px;
border: 1px solid red;
display: none;}
</style>
<script type="text/javascript">
window.onload= function(){
var oBtn = document.getElementById('btn');
var oDiv = document.getElementById('div1');
oBtn.onclick = function(ev){
var ev = ev || event;
ev.cancelBubble = true;
oDiv.style.display = 'block';
}
document.onclick = function(){
setTimeout(function(){
oDiv.style.display = 'none';
},1000);
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="按鈕" />
<div id="div1">
</div>
</body>
</html>
----------------------------------------------------------------------------------
冒泡例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="{CHARSET}">
<title></title>
<style>
#div1{
width: 100px;
height: 200px;
background: red;
position:absolute;left: -100px;top: 100px;}
#div2{
width: 30px;height: 60px;position: absolute;right: -30px;top: 70px;background: black;color: white;text-align: center;
}
</style>
<script type="text/javascript">
window.onload= function(){
var oDiv = document.getElementById('div1');
oDiv.onmouseover = function(){
this.style.left = '0px';
}
oDiv.onmouseout = function(){
this.style.left = '-100px';
}
}
</script>
</head>
<body>
<div id="div1">
<div id="div2">分享到</div>
</div>
</body>
</html>