js中的事件委託(事件代理)

NO IMAGE

1、事件流

      事件流描述的是從頁面接收到事件的順序,包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。最先發生的是事件捕獲,然後是具體的實際目標收到事件,最後才是冒泡階段,可以在這個階段對事件做出響應。

2、添加事件監聽

(1)給元素添加事件監聽的方法,可以直接在html上添加或者在JavaScript中指定的事件處理程序,但是需要注意,這種以‘on’開頭的事件屬於‘DOM0’級事件,重複定義時會覆蓋掉原事件,而使用addEventListener,則不會覆蓋之前添加的。

<input id='btn' value='click me' onclick='alert(this.value)'>

(2)使用addEventListener/removeEventListener方法,所有dom節點都包含這方法,傳入三個參數:事件名、處理事件的函數、標示在捕獲還是在冒泡階段調用回調函數的布爾值。

addEventListener添加的事件處理函數只能用removeEventListener方法移除,傳入 參數與addEventListener相同,意味著addEventListener添加的匿名函數無法移除,所以在用addEventListener添加處理函數時不能使用匿名函數。環境不支持addEventListener的時候,可以使用attachEvent/detachEvent。

let btn = document.getElementById('btn')
let handler = function () {alert(this.id)}
btn.addEventListener('click', handler,false)
btn.removeEventListener('click', handler,false)

3、事件委託

      在父元素上添加可以處理子元素事件的事件處理函數。

利用了事件冒泡,指定一個事件處理函數,來處理同一個類型的多個事件。

target是觸發事件的最具體的元素,currenttarget是綁定事件的元素(在函數中一般等於this)。

<div id="outter">
<div id="inner"></div>
</div>
var outter = document.querySelector('#outter')
outter.addEventListener('click',function(e){
console.log(e.target.id)  //inner
console.log(e.currentTarget.id)  //outter
console.log(this === e.currentTarget)  //true
},false)

      當我們需要對很多元素添加事件的時候,可以通過將事件添加到它們的父節點而將事件委託給父節點來觸發處理函數。

       這主要得益於瀏覽器的事件冒泡機制。

優點:

(1)管理的函數變少了,不需要為每個元素都添加監聽函數,對於同一個父節點下面類似的子元素,可以通過委託給父元素的監聽函數來處理事件。

(2)可以方便地動態添加和修改元素,不需要因為元素的改動而修改事件綁定。

(3)JavaScript和DOM節點之間的關聯變少了。這樣也就減少了因循環引用而帶來的內存洩漏發生的概率。

獲取目標元素:

function getEventTarget(e) {
//event屬性兼容寫法
e = e || window.event;
//獲取目標元素兼容寫法
return e.target || e.srcElement;
}

處理函數:

function editCell(e) {
var target = getEventTarget(e);
if(target.tagName.toLowerCase() == 'td') {
// DO SOMETHING WITH THE CELL
}
}

例子:

var oUl=document.getElementById("parent-list");
var aLi=oUl.getElementsByTagName('li');
function target(e) {
var oEvent=e||event;
return oEvent.target||oEvent.srcElement;
}
oUl.addEventListener('click',function (e) {
var oEvent=e||event;
var targets=target(oEvent);
if (targets.tagName.toLowerCase()=='li') {
console.log(targets.id);
}
})

注:為父節點添加一個click事件,當子節點被點擊的時候,click事件會從子節點開始向上冒泡。父節點捕獲到事件之後,通過判斷e.target.nodeName來判斷是否為我們需要處理的節點。並且通過e.tartget拿到了被點擊的LI節點。從而可以獲取到相應的信息,並作處理。

jQuery中的delegate函數:

$("#link-list").delegate("a", "click", function(){
// "$(this)" is the node that was clicked
console.log("you clicked a link!",$(this));
});

注:jQuery的delegate的方法需要三個函數,一個選擇器,一個事件名稱,和事件處理函數。

相關文章

ElementUI樹形表格

瀏覽器兼容性js

前端性能優化的方法

原型鏈