javascript事件監聽,事件冒泡/捕獲總結
一、javascript事件監聽的三種方法
element.addEventListener(type, listener[, useCapture]); // IE6~8不支援
element.attachEvent('on' + type, listener); // IE6~10支援, IE11不支援
element.'on' + type = function(){} // 所有瀏覽器
以click 點選事件為例:
<!DOCTYPE HTML> <html lang="zh-cn"> <head> <meta charset="utf-8" /> <title>Javascript</title> <style> *{margin: 0;padding: 0;} #big{width: 300px;height: 180px;background-color: orange;margin: 20px auto;} #small{width: 150px;height: 100px;background-color: blue;} </style> </head> <body> <div id="big"> <div id="small"></div> </div> <script> window.onload = function(){ var oSmall = document.getElementById('small'); var oBig = document.getElementById('big'); //第一種:所有瀏覽器支援 oBig.onclick = function(){ console.log('Big Div'); } //第二種:ie8及ie8以下不支援 oBig.addEventListener('click', function(){ console.log('Big Div'); }, true); //第三種:ie6~ie10支援 oBig.attachEvent('onclick', function(){ console.log('Big Div'); }); } </script> </body> </html>
二、事件捕獲與事件冒泡
關於事件的捕獲與冒泡,引用一段文字來說明:
很久以前有個叫Netscape的姑娘,她制訂了Javascript的一套事件驅動機制(即事件捕獲)
後來又有一個叫“IE”的小子,這孩子比較傲氣,他認為“憑什麼我要依照你的規則走”,於是他又創造了一套自己的規則(事件冒泡)
再後來,有個叫W3C的媒婆,想撮合這兩個孩子,將他們的特點融合在了一起,這下,事件產生的順序變成:
事件從根節點開始,逐級派送到子節點,若節點綁定了事件動作,則執行動作,然後繼續走,這個階段稱為“捕獲階段(Capture)”;
執行完捕獲階段後,事件由子節點往根節點派送,若節點綁定了事件動作,則執行動作,然後繼續走,這個階段稱為“冒泡階段(Bubble)”。
善良的Netscape以及其姐妹們都接受了媒婆的建議,採用了新的事件規則,而驕傲固執的IE小子始終按照自己的規則執行。最終使得這成為困擾前端開發人員的相容性問題之一。
幾個要點:
(1)通過 element.onclick、element.attackEvent('onclick', function(){}) 來監聽事件,均為冒泡機制。例子:
<!DOCTYPE HTML> <html lang="zh-cn"> <head> <meta charset="utf-8" /> <title>Javascript</title> <style> *{margin: 0;padding: 0;} #big{width: 300px;height: 180px;background-color: orange;margin: 20px auto;} #small{width: 150px;height: 100px;background-color: blue;} </style> </head> <body> <div id="big"> <div id="small"></div> </div> <script> window.onload = function(){ var oSmall = document.getElementById('small'); var oBig = document.getElementById('big'); oBig.onclick = function(){ console.log('Big Div'); } oSmall.onclick = function(){ console.log('Small Div'); } // 當點選 div#small時,先後輸出: // Small Div // Big Div } </script> </body> </html>
(2)w3c 標準中的 addEventListener 方法
W3C規範中定義了3個事件階段,依次是捕獲階段、目標階段、冒泡階段(即上文引用文字中的藍色字型部分)。addEventListener 中的第三個引數 true/false,規定了該事件在捕獲階段執行,還是在冒泡階段執行。
例項說明:
<!DOCTYPE HTML>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<title>Javascript</title>
<style>
*{margin: 0;padding: 0;}
#big{width: 300px;height: 180px;background-color: orange;margin: 20px auto;}
#small{width: 150px;height: 100px;background-color: blue;}
</style>
</head>
<body>
<div id="big">
<div id="small"></div>
</div>
<script>
window.onload = function(){
var oSmall = document.getElementById('small');
var oBig = document.getElementById('big');
oSmall.addEventListener('click', function(){
console.log('Small Div 捕獲');
}, true);
oBig.addEventListener('click', function(){
console.log('Big Div 冒泡');
});
oBig.addEventListener('click', function(){
console.log('Big Div 捕獲');
}, true);
document.addEventListener('click', function(){
console.log('Document 冒泡');
});
document.addEventListener('click', function(){
console.log('Document 捕獲');
}, true);
}
</script>
</body>
</html>
輸出順序如下圖所示:
當我們點選 div#small 元素時,它是這樣的過程:
第一階段 —— 捕獲階段:所以,"Document 捕獲" 最先被執行,然後是“Big Div 捕獲”,最後是“Small Div 捕獲”;
第二階段 —— 目標階段:到達 div#small 元素,然後,下一步,進入到冒泡階段;
第三階段 —— 冒泡階段:Small Div 沒有事件冒泡,所以,冒泡到 Big Div,發現有事件冒泡,輸出“Big Div 冒泡”, 再繼續往上冒泡,最後輸出“Document 冒泡”。整個過程結束。
三、事件監聽在不同瀏覽器下相容寫法
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
文字引用:
http://www.cnblogs.com/aji88/archive/2012/07/20/2600492.html