若是要把HTML元素的事件與某個函數綁定起來,能夠有下面三種方法,以最多見的「點擊」事件爲例。html
方法一:shell
直接在對應的HTML元素標籤上綁定函數函數
<button id='submit' onclick='onClickFn()'>Click Me!</button>
方法二:測試
在JavaScript代碼裏面指定元素的「onclick」方法spa
var btn = document.getElementById('submit'); btn.onclick = onClickFn;
方法三:code
使用事件監聽綁定方法htm
var btn = document.getElementById('submit'); btn.addEventListener('click', onClickFn, false);
三種方法均可以在button被點擊的時候調用onClickFn函數,可是有所區別。事件
第一種方法不推薦,由於違反了HTML與JavaScript分離的準則;ip
第二種方法只能給一個事件綁定一個響應函數,重複綁定會覆蓋以前的綁定;get
第三種方法比較推薦,能夠綁定多個不一樣的函數。
不過退步推薦不是重點,重點是第三種方法中的第三個參數爲什麼是「false」?
當鼠標點擊所看到的的按鈕時,其實發生了一系列的事件傳遞,能夠想象一下,button其實是被body「包裹」起來的,body是被html「包裹」起來的,html是被document「包裹」起來的,document是被window「包裹」起來的。因此,在你的鼠標點下去的時候,最早得到這個點擊的是最外面的window,而後通過一系列傳遞纔會傳到最後的目標button,當傳到button的時候,這個事件又會像水底的泡泡同樣慢慢往外層穿出,直到window結束。
綜上,一個事件的傳遞過程包含三個階段,分別稱爲:
捕獲階段,目標階段,冒泡階段
目標指的就是包裹得最深的那個元素。
假設HTML有以下元素:
<div id='d'> <p id='p'> <span id='s'>Click Me!</span> </p> </div>
JavaScript代碼以下:
var div = document.getElementById('d'); var p = document.getElementById('p'); var span = document.getElementById('s'); function onClickFn (event) { var tagName = event.currentTarget.tagName; var phase = event.eventPhase; console.log(tagName, phase); } div.addEventListener('click', onClickFn, false); p.addEventListener('click', onClickFn, false);
此時,點擊「Click Me!」,便可在控制檯看到以下結果:
P 3 DIV 3
其中「3」和「冒泡階段」對應。
能夠看出,p和div都是在冒泡階段相應了事件,因爲冒泡的特性,裹在裏層的p率先作出響應。
若是把上面代碼裏面中addEventListener的第三個參數設置爲true,那麼運行的結果以下:
DIV 1 P 1
由此,addEventListener的第三個參數設置爲true和false的區別已經很是清晰了:
true表示該元素在事件的「捕獲階段」(由外往內傳遞時)響應事件;
false表示該元素在事件的「冒泡階段」(由內向外傳遞時)響應時間。
至此,你可能會有疑問,還有一個「目標階段」呢?
您不妨給span元素綁定事件,本身測試一下。
在冒泡階段,若是不但願事件繼續往上傳播,例如,冒泡的p的時候就中止傳播,那麼,能夠在p的事件回調函數裏面這麼寫:
function onClickFn (event) { // code here event.stopPropagation(); }
這樣,冒泡到p的時候,就不會再向上傳播了,即,div不會收到冒泡上來的click事件。
若是還想把其它與p綁定的響應函數的事件也「屏蔽」掉,須要把stopPropagation換爲stopImmediatePropagation。
【END】