JavaScript的事件監聽、捕獲和冒泡

 在前端開發中,咱們常常須要對某些事件進行監聽。這樣只要在指定的元素上觸發了該事件,就會執行一個回調函數來進行相關的操做。javascript

  而JavaScript中事件監聽的方法總共有三種,分別以下:前端

  • element.addEventListener(type, listener[, useCapture]);  //IE6~8不支持
  • element.attachEvent('on' + type, listener)     //支持IE6~10,IE11不支持
  • element['on' + type] = function(){}     //支持全部瀏覽器

  demo:java

function cb(){
  console.log(1);  
}

element.addEventListener('click', cb, false);
element.attachEvent('onclick', cb);
element.onclick = cb;

  

參數解釋:
  type:事件類型
  listener:事件出發後的回調函數
  useCapture:是否使用捕獲,若是值爲true,useCapture表示用戶但願發起捕獲。在發起捕獲以後,只要DOM子樹下發生了該事件類型,都會先被該事件監聽器捕獲,而後再被派發到DOM子樹中的事件監聽器中。而且向上冒泡的事件不會觸發那些發起捕獲的事件監聽器。useCapture默認值是true。瀏覽器

  addEventListener是W3C工做組在DOM Level 2開始引入的一個註冊事件監聽器的方法,而在此以前,傳統的事件監聽方法是經過element['on' + type]的方式來註冊的。它們的主要區別是element['on' + type]的方式沒法使用事件捕獲,而且element['on' + type]不支持對同一個元素的同一個事件註冊多個事件監聽器。以下面的例子所示,元素被點擊以後只會輸出1,而不會輸出0和1。函數

element.onclick = function(){ console.log(0); }
element.onclick = function(){ console.log(1); }

然而addEventListener方法在IE6~8的瀏覽器中不被支持。那麼在低版本的IE中怎麼來爲同一個事件註冊多個事件監聽器呢?原來IE從IE5.0系列開始就引入了attachEvent()方法來支持這一特性。但遺憾的是該方法也不支持事件捕獲。而且從IE11開始,這個方法已經被棄用。spa

  談談事件的捕獲與冒泡code

 

W3C規範中定義了3個事件階段,依次是捕獲階段、目標階段、冒泡階段。事件對象按照上圖的傳播路徑依次完成這些階段。若是某個階段不支持或事件對象的傳播被終止,那麼該階段就會被跳過。舉個例子,若是Event.bubbles屬性被設置爲false,那麼冒泡階段就會被跳過。若是Event.stopPropagation()在事件派發前被調用,那麼全部的階段都會被跳過。對象

  • 捕獲 階段:在事件對象到達事件目標以前,事件對象必須從window通過目標的祖先節點傳播到事件目標。 這個階段被咱們稱之爲捕獲階段。在這個階段註冊的事件監聽器在事件到達其目標前必須先處理事件。
  • 目標 階段:事件對象到達其事件目標。 這個階段被咱們稱爲目標階段。一旦事件對象到達事件目標,該階段的事件監聽器就要對它進行處理。若是一個事件對象類型被標誌爲不能冒泡。那麼對應的事件對象在到達此階段時就會終止傳播。
  • 冒泡 階段:事件對象以一個與捕獲階段相反的方向從事件目標傳播通過其祖先節點傳播到window。這個階段被稱之爲冒泡階段。在此階段註冊的事件監聽器會對相應的冒泡事件進行處理。

  在一個事件完成了全部階段的傳播路徑後,它的Event.currentTarget會被設置爲null而且Event.eventPhase會被設爲0。Event的全部其餘屬性都不會改變(包括指向事件目標的Event.target屬性)blog

 

  知識連接:token

  一、Event.currentTarget屬性:currentTarget 事件屬性返回其監聽器觸發事件的節點,即當前處理該事件的元素、文檔或窗口。在捕獲和起泡階段,該屬性是很是有用的,由於在這兩個節點,它不一樣於 target 屬性。

/*HTML代碼*/
<p id="p1" onmousedown="getEventTrigger(event)">點擊我試試</p>

/*JavaScript代碼*/
function getEventTrigger(event){
var x = event.currentTarget;
alert("The id of the triggered element: " + x.id);
}

 二、Event.eventPhase屬性:eventPhase 屬性返回事件傳播的當前階段。它的值是下面的三個常量之一,它們分別表示捕獲階段、正常事件派發和起泡階段。

    

window.onload = function(){ var btn = document.getElementById("btn"); btn.onclick = function(event){ alert(event.eventPhase);  //2 } document.body.addEventListener("click",function(event){ alert(event.eventPhase);  //1 },true); document.body.onclick = function(event){ alert(event.eventPhase);  //3 }}

相關文章
相關標籤/搜索