學習內容與資源來自這位大佬:傳送門,啓動!html
尤爲是關於爲何要使用事件委託的原理,是原樣搬運過來的:node
通常來講,dom須要有事件處理程序,咱們都會直接給它設事件處理程序就行了,那若是是不少的dom須要添加事件處理呢?好比咱們有100個li,每一個li都有相同的click點擊事件,可能咱們會用for循環的方法,來遍歷全部的li,而後給它們添加事件,那這麼作會存在什麼影響呢?瀏覽器
在JavaScript中,添加到頁面上的事件處理程序數量將直接關係到頁面的總體運行性能,由於須要不斷的與dom節點進行交互,訪問dom的次數越多,引發瀏覽器重繪與重排的次數也就越多,就會延長整個頁面的交互就緒時間,這就是爲何性能優化的主要思想之一就是減小DOM操做的緣由;若是要用事件委託,就會將全部的操做放到js程序裏面,與dom的操做就只須要交互一次,這樣就能大大的減小與dom的交互次數,提升性能;性能優化
每一個函數都是一個對象,是對象就會佔用內存,對象越多,內存佔用率就越大,天然性能就越差了(內存不夠用,是硬傷,哈哈),好比上面的100個li,就要佔用100個內存空間,若是是1000個,10000個呢,那隻能說呵呵了,若是用事件委託,那麼咱們就能夠只對它的父級(若是隻有一個父級)這一個對象進行操做,這樣咱們就須要一個內存空間就夠了,是否是省了不少,天然性能就會更好。dom
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- 定義:事件委託又稱事件代理,利用事件冒泡的原理, 將一個父容器內的多個子元素的相同的事件類型用綁定在父元素上的一個事件處理程序,而非爲子元素挨個綁定監聽事件 -->
<!-- 優勢:在刪除一個子元素時,不用特地爲其刪除監聽事件,而在新增一個子元素時,也不用去新增點擊事件 -->
<ul id="container">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
<script>
var parent = document.getElementById("container"); var list = document.getElementsByTagName("li"); for(var i = 0;i<list.length;i++){ list[i].onclick = function(){ console.log(this.innerText); } } //爲何要使用事件委託? parent.onclick = function(){ console.log(this);//這個this是parent而不是內部的元素!
}
//那麼如何使得代理的事件觸發以後與綁定在原來節點上的事件做用一致?使用event對象的target屬性 parent.onclick = function(ev){ var event = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == "li"){ alert(target.innerText); //若是按鈕具備不一樣時事件如何使用事件代理?
switch (target.innerText) { case 1: alert("這是1號~"); break; case 2: alert("這是2號~"); default: alert("這是其餘的~"); break; } } }
</script>
</html>
那什麼樣的事件能夠用事件委託,什麼樣的事件不能夠用呢?函數
適合用事件委託的事件:click,mousedown,mouseup,keydown,keyup,keypress。性能
值得注意的是,mouseover和mouseout雖然也有事件冒泡,可是處理它們的時候須要特別的注意,由於須要常常計算它們的位置,處理起來不太容易。學習
不適合的就有不少了,舉個例子,mousemove,每次都要計算它的位置,很是很差把控,在不如說focus,blur之類的,自己就沒用冒泡的特性,天然就不能用事件委託了。優化
JQuery中的事件委託:ui
在整理時,發現jQuery從1.7以後就不推薦live()和delegate()方法了,因此儘可能仍是使用on()方法更好,用法就如上圖,$("#parent").on('mouseover','#child')~