先通過一個例子來引出事件委托:
假設有一個ul父節點,包含了很多li的子節點,點擊li觸發相應的事件
<ul id="parent"> <li>item 1</li> <li>item 2</li> <li>item 3</li> <li>item 4</li> <li>item 5</li> <li>item 6</li> </ul>
我們通常的寫法是為每一個li都添加一個onclick事件監聽。
window.onload = function(){ var parent = document.getElementById('parent'); var children = parent.getElementsByTagName('li'); for(var i=0,len=children.length; i<len;i++){ children[i].onclick = function(){ alert(this.innerHTML); } } }
如果這個ul的子元素需允許無限態的添加時,就會出現問題:
1.新添加的元素不會綁定事件,所以需要每次添加li的同時要添加綁定事件
2.綁定的事件越多,性能越差
為了解決這個問題,可以用事件代理。更簡單的方法是使用事件委托。
JavaScript中事件傳播過程:
事件的處理流成分為三階段:
一、事件捕獲階段:當某個元素觸發某個事件時,首先會觸發根元素document,然后事件將沿着dom樹向下傳播給目標節點的每一個祖先節點,直到目標節點。
二、目標階段:到達目標元素之后,執行目標元素的事件處理函數
三、事件冒泡階段:從目標元素開時,事件將沿着DOM樹向上傳播,直到根節點。
下面引用一張網上的圖:
那么到了正題上了,事件委托就是利用事件冒泡原理,把處理任務委托給父元素或者祖先元素(通常用父元素),我們通過目標對象來判斷事件源,並執行事件處理。
事件委托實現:
網上搜索有太多的例子,下面把剛開始的例子用事件委托的方法來實現。用事件委托的方法,動態添加的元素不需要再綁定事件了。
<ul id="parent"> <li>item 1</li> <li>item 2</li> <li>item 3</li> <li>item 4</li> <li>item 5</li> <li>item 6</li> </ul> <script> window.onload = function(){ var parent = document.getElementById('parent'); parent.addEventListener('click',function(event){ var event = event || window.event; var target = event.target || event.srcElement; if(target.nodeName.toUpperCase() == 'LI'){ alert(target.innerHTML) } },false) } </script>
事件委托帶來的優點:
1.不需要為每一個元素都添加監聽事件而是通過委托給父元素來處理。這樣就減少了內存,性能提高了
2.可以方便動態添加元素。不需要再為新添加的元素重新綁定事件。