深刻理解DOM事件機制系列第一篇——事件流

前面的話

  javascript操做CSS稱爲腳本化CSS,而javascript與HTML的交互是經過事件實現的。事件就是文檔或瀏覽器窗口中發生的一些特定的交互瞬間,而事件流(又叫事件傳播)描述的是從頁面中接收事件的順序。本文將詳細介紹該部分的內容javascript

 

歷史

  當瀏覽器發展到第四代時(IE4及Netscape4),瀏覽器開發團隊遇到了一個頗有意思的問題:頁面的哪一部分會擁有某個特定的事件?想象畫在一張紙上的一組同心圓。若是把手指放在圓心上,那麼手指指向的不是一個圓,而是紙上的全部圓html

  兩家公司的瀏覽器開發團隊在看待瀏覽器事件方面仍是一致的。若是單擊了某個按鈕,他們都認爲單擊事件不單單發生在按鈕上,甚至也單擊了整個頁面java

  但有意思的是,IE和Netscape開發團隊竟然提出了差很少是徹底相反的事件流的概念。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕獲流瀏覽器

 

事件冒泡

  IE的事件流叫作事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上傳播到較爲不具體的節點(文檔)spa

  如下列HTML結構爲例,說明事件冒泡、事件捕獲及事件流3d

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<body>
<div></div>
</body>    
</html>

  若是單擊了頁面中的<div>元素,那麼這個click事件沿DOM樹向上傳播,在每一級節點上都會發生,按照以下順序傳播:code

(1)    <div>
(2)    <body>
(3)    <html>
(4)    document

  [注意]全部現代瀏覽器都支持事件冒泡,但在具體實如今仍是有一些差異。IE九、Firefox、Chrome、Safari將事件一直冒泡到window對象htm

(1)    <div>
(2)    <body>
(3)    <html>
(4)    document
(5)    window
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<body>
<div id="box" style="height:100px;width:300px;background-color:pink;"></div>
<button id="reset">還原</button>
<script>
//IE8-瀏覽器返回div body html document
//其餘瀏覽器返回div body html document window
reset.onclick = function(){history.go();}
box.onclick = function(){box.innerHTML += 'div\n';}
document.body.onclick = function(){box.innerHTML += 'body\n';}
document.documentElement.onclick = function(){box.innerHTML += 'html\n';}
document.onclick = function(){box.innerHTML += 'document\n';}
window.onclick = function(){box.innerHTML += 'window\n';}
</script>
</body>    
</html>

事件捕獲

  事件捕獲的思想是不太具體的節點應該更早接收到事件,而最具體的節點應該最後接收到事件。事件捕獲的用意在於在事件到達預約目標以前就捕獲它對象

  以一樣的HTML結構爲例,說明事件捕獲blog

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<body>
<div></div>
</body>    
</html>

  在事件捕獲過程當中,document對象首先接收到click事件,而後事件沿DOM樹依次向下,一直傳播到事件的實際目標,即<div>元素

(1)    document
(2)    <html>
(3)    <body>
(4)    <div>

  [注意]IE九、Firefox、Chrome、Safari等現代瀏覽器都支持事件捕獲,可是從window對象開始捕獲

(1)    window
(2)    document
(3)    <html>
(4)    <body>
(5)    <div>

  addEventListener()方法中的第三個參數設置爲true時,即爲事件捕獲階段

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<body>
<div id="box" style="height:100px;width:300px;background-color:pink;"></div>
<button id="reset">還原</button>
<script>
//IE8-瀏覽器不支持
//其餘瀏覽器返回window document html body div
reset.onclick = function(){history.go();}
box.addEventListener('click',function(){box.innerHTML += 'div\n'},true)
document.body.addEventListener('click',function(){box.innerHTML += 'body\n';},true);
document.documentElement.addEventListener('click',function(){box.innerHTML += 'html\n';},true);
document.addEventListener('click',function(){box.innerHTML += 'document\n';},true);
window.addEventListener('click',function(){box.innerHTML += 'window\n';},true);
</script>
</body>    
</html>

事件流

  事件流又稱爲事件傳播,DOM2級事件規定的事件流包括三個階段:事件捕獲階段(capture phase)、處於目標階段(target phase)和事件冒泡階段(bubbling phase)

  首先發生的是事件捕獲,爲截獲事件提供了機會。而後是實際的目標接收到事件,最後一個階段是冒泡階段,能夠在這個階段對事件作出響應

相關文章
相關標籤/搜索