事件委托
事件委托,通俗地來講,就是把一個元素響應事件(click、keydown......)的函數委托到另一個元素。
比如說有一個清單 ul,清單之中有大量的清單項
<a>
标簽:
<ul id="parent-list">
<li><a href="javascript:;" class="my_link">超連結一</a></li>
<li><a href="javascript:;" class="my_link">超連結二</a></li>
<li><a href="javascript:;" class="my_link">超連結三</a></li>
</ul>
複制
當我們的滑鼠移到
<a>
标簽上的時候,需要擷取此
<a>
的相關資訊并飄出懸浮窗以顯示詳細資訊,或者當某個
<a>
被點選的時候需要觸發相應的處理事件。我們通常的寫法,是為每個
<a>
都綁定類似onMouseOver或者onClick之類的事件監聽:
window.onload = function(){
var parentNode = document.getElementById("parent-list");
var aNodes = parentNode.getElementByTagName("a");
for(var i=0, l = aNodes.length; i < l; i++){
aNodes[i].onclick = function() {
console.log('我是超連結 a 的單擊相應函數');
}
}
}
複制
但是,上面的做法過于消耗記憶體和性能。我們希望,隻綁定一次事件,即可應用到多個元素上,即使元素是後來添加的。
是以,比較好的方法就是把這個點選事件綁定到他的父層,也就是
ul
上,然後在執行事件函數的時候再去比對判斷目标元素。如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
window.onload = function() {
// 擷取父節點,并為它綁定click單擊事件。 false 表示事件在冒泡階段觸發(預設)
document.getElementById('parent-list').addEventListener('click', function(event) {
event = event || window.event;
// e.target 表示:觸發事件的對象
//如果觸發事件的對象是我們期望的元素,則執行否則不執行
if (event.target && event.target.className == 'link') {
// 或者寫成 if (event.target && event.target.nodeName.toUpperCase() == 'A') {
console.log('我是ul的單擊響應函數');
}
}, false);
};
</script>
</head>
<body>
<ul id="parent-list" style="background-color: #bfa;">
<li>
<p>我是p元素</p>
</li>
<li><a href="javascript:;" class="link">超連結一</a></li>
<li><a href="javascript:;" class="link">超連結二</a></li>
<li><a href="javascript:;" class="link">超連結三</a></li>
</ul>
</body>
複制
上方代碼,為父節點注冊 click 事件,當子節點被點選的時候,click事件會從子節點開始向父節點冒泡。父節點捕獲到事件之後,開始執行方法體裡的内容:通過判斷 event.target 拿到了被點選的子節點
<a>
。進而可以擷取到相應的資訊,并作處理。
換而言之,參數為false,說明事件是在冒泡階段觸發(子元素向父元素傳遞事件)。而父節點注冊了事件函數,子節點沒有注冊事件函數,此時,會在父節點中執行函數體裡的代碼。
總結:事件委托是利用了冒泡機制,減少了事件綁定的次數,減少記憶體消耗,提高性能。