1. 程式人生 > 前端設計 >DOM 事件模型/機制和事件委託

DOM 事件模型/機制和事件委託

1,DOM級別

有DOM0~4級,其中dom1級沒有定義相關事件就不是標準的dom事件,它似乎是專注於 HTML 和 XML 文件模型

  • DOM0級(HTML事件):element.onclick=function(event){}
  <button type="button" onclick="hi()"></button>
  function hi() {
      console.log('Hi World');
  }
複製程式碼
  1. 缺點一:一個元素同種型別的事件只能註冊一個事件處理程式,多事件會被互相覆蓋
  2. 卻大的缺點:HTML和JS耦合太強,如果我們需要修改函式名 就必須修改兩個地方
  3. 優點:是不需要操作DOM來完成事件繫結
  • DOM2級:element.addEventListener('click',function(event){},false)冒泡
    <button id="btn" type="button"></button>
    var btn = document.getElementById('btn');    
    function hi() {
        console.log('hi World');
    }    
    btn.addEventListener('click',hi,false
); //沒有on btn.addEventlistener('mouseover',showfn,false) //允許新增多個事件 // btn.removeEventListener('click',false); 解綁事件 複製程式碼
  1. 同一個元素上的同類型事件可以註冊多個處理函式。事件觸發時按照註冊順序觸發。
  2. 支援捕獲和冒泡,當布林值為ture是捕獲,falsy為冒泡()、
  3. 注意,IE事件處理程式沒有第三個引數,因為IE早期版本只支援事件冒泡,所以預設就是事件冒泡。
  • DOM3級:element.addEventListener('keyup',false),新增的滑鼠鍵盤事件

可以自定義事件 在DOM2級的事件上添加了很多事件型別 UI事件 load,scroll 焦點事件, blur,focus 滑鼠事件,dbclick,mouseup ...

2,DOM事件模型和事件流

DOM事件模型分別為捕獲和冒泡。一個事件發生後,會在子元素和父元素之間傳播。這種傳播分成三個階段。

DOM事件模型示意圖

1,捕獲階段

事件從window物件自上而下向目標節點傳播的階段 
addEventListener的第三個引數bool為ture 
不可取消,但冒泡可以阻止
複製程式碼

2,目標階段(target):真正的目標節點正在處理事件的階段

3,冒泡階段:事件從目標節點自下而上向window物件傳播的階段。

e.stopPropagation()中斷冒泡,瀏覽器不再向上傳播// 一般用於封裝某些獨立的元件
一些不能取消的冒泡事件:Bubbles表示是否冒泡;Cancelable表示是否支援開發者取消冒泡 具體口檢視mdn文件,英文版更全
複製程式碼
<div class="outter" hiOutter()>
  <div class="middle" hiMiddle()>
    <div class="inner" hiInner()>
      我目標就在此
    </div>
  </div>
</div>

function hiOutter() {
    console.log('hiOutter');
}
function hiMiddle() {
    console.log('hiMiddle');
} 
function hiInner() {
    console.log('hiInne');
} 
複製程式碼

事件委託

  1. 定義

事件委託指的是不在事件的發生地(直接DOM)上設定監聽函式,而是在其父元素上設定監聽函式,通過事件冒泡,父元素可以監聽到被觸發的子元素事件,通過判斷事件發生元素DOM的型別,來作出不同的響應。當子元素有很多時,使用事件委託可以避免對特定的每個節點新增事件監聽器,事件監聽被新增到它們的父元素上,事件監聽函式這是可以從子元素上冒泡上來的事件,找到是哪個子元素事件。

  1. 事件委託舉例

最經典的就是ul和li標籤的事件監聽,比如我們在新增事件時候,採用事件委託機制,不會在li標籤上直接新增,而是在ul父元素上新增。

第一步:給父元素繫結事件。給元素ul新增繫結事件,通過addEventListener為點選事件click新增繫結。

第二步:監聽子元素的冒泡事件。這裡預設是冒泡,點選子元素li會向上冒泡。

第三步:找到是哪個子元素的事件。 通過匿名回撥函式的引數event用來接收事件物件,通過event.target獲取觸發事件的目標。

  1. 使用事件委託的好處
  • 省記憶體
  • 動態繫結