DOM 事件模型/機制和事件委託
阿新 • • 發佈:2020-06-29
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');
}
複製程式碼
- 缺點一:一個元素同種型別的事件只能註冊一個事件處理程式,多事件會被互相覆蓋
- 卻大的缺點:HTML和JS耦合太強,如果我們需要修改函式名 就必須修改兩個地方
- 優點:是不需要操作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); 解綁事件
複製程式碼
- 同一個元素上的同類型事件可以註冊多個處理函式。事件觸發時按照註冊順序觸發。
- 支援捕獲和冒泡,當布林值為ture是捕獲,falsy為冒泡()、
- 注意,IE事件處理程式沒有第三個引數,因為IE早期版本只支援事件冒泡,所以預設就是事件冒泡。
- DOM3級:element.addEventListener('keyup',false),新增的滑鼠鍵盤事件
可以自定義事件 在DOM2級的事件上添加了很多事件型別 UI事件 load,scroll 焦點事件, blur,focus 滑鼠事件,dbclick,mouseup ...
2,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');
}
複製程式碼
事件委託
- 定義
事件委託指的是不在事件的發生地(直接DOM)上設定監聽函式,而是在其父元素上設定監聽函式,通過事件冒泡,父元素可以監聽到被觸發的子元素事件,通過判斷事件發生元素DOM的型別,來作出不同的響應。當子元素有很多時,使用事件委託可以避免對特定的每個節點新增事件監聽器,事件監聽被新增到它們的父元素上,事件監聽函式這是可以從子元素上冒泡上來的事件,找到是哪個子元素事件。
- 事件委託舉例
最經典的就是ul和li標籤的事件監聽,比如我們在新增事件時候,採用事件委託機制,不會在li標籤上直接新增,而是在ul父元素上新增。
第一步:給父元素繫結事件。給元素ul新增繫結事件,通過addEventListener為點選事件click新增繫結。
第二步:監聽子元素的冒泡事件。這裡預設是冒泡,點選子元素li會向上冒泡。
第三步:找到是哪個子元素的事件。 通過匿名回撥函式的引數event用來接收事件物件,通過event.target獲取觸發事件的目標。
- 使用事件委託的好處
- 省記憶體
- 動態繫結