在DOM事件對象中有兩個屬性總是時不時的困擾我,就是target和currentTarget,有時候很迷惑分不清兩者的區別,因此有必要把這兩個屬性好好梳理一下,加深理解,以便日后的查詢。
MDN中對target的解釋為,一個觸發事件的對象的引用, 當事件處理程序在事件的冒泡或捕獲階段被調用時。
而對於currentTarget,它指的是當事件遍歷DOM時,標識事件的當前目標。它總是引用事件處理程序附加到的元素,而不是event.target,它標識事件發生的元素。
舉個例子來說明。
事件冒泡階段
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <ul> <li>hello 1</li> <li>hello 2</li> <li>hello 3</li> <li>hello 4</li> </ul> <script> let ul = document.querySelectorAll('ul')[0] let aLi = document.querySelectorAll('li') ul.addEventListener('click',function(e){ let oLi1 = e.target let oLi2 = e.currentTarget console.log(oLi1) // 被點擊的li console.log(oLi2) // ul console.og(oLi1===oLi2) // false }) </script> </body> </html>
我們知道,e.target可以用來實現事件委托,該原理是通過事件冒泡(或者事件捕獲)給父元素添加事件監聽,e.target指向引發觸發事件的元素,如上述的例子中,e.target指向用戶點擊的li,由於事件冒泡,li的點擊事件冒泡到了ul上,通過給ul添加監聽事件而達到了給每一個li添加監聽事件的效果,而e.currentTarget指向的是給綁定事件監聽的那個對象,即ul,從這里可以發現,e.currentTarget===this返回true,而e.target===this返回false。e.currenttarget和e.target是不相等的。
注意,在jQuery提供的on方法中,e.currentTarget與該方法接收的第二個參數有關,根據jQuery的文檔描述
如果省略selector或者是null,那么事件處理程序被稱為直接事件 或者 直接綁定事件 。每次選中的元素觸發事件時,就會執行處理程序,不管它直接綁定在元素上,還是從后代(內部)元素冒泡到該元素的
當提供selector參數時,事件處理程序是指為委派事件(事件委托或事件代理)。事件不會在直接綁定的元素上觸發,但當selector參數選擇器匹配到后代(內部元素)的時候,事件處理函數才會被觸發。jQuery 會從 event target 開始向上層元素(例如,由最內層元素到最外層元素)開始冒泡,並且在傳播路徑上所有綁定了相同事件的元素若滿足匹配的選擇器,那么這些元素上的事件也會被觸發。
<!DOCTYPE html> <html> <head> <script src="//code.jquery.com/jquery-1.9.1.min.js"></script> <meta charset="utf-8"> <title>JS Bin</title> <style> li{ padding: 5px; border: 1px solid red; } span{ border: 1px solid #000; } </style> </head> <body> <ul> <li><span>hello 1</span></li> <li><span>hello 1</span></li> <li><span>hello 1</span></li> <li><span>hello 1</span></li> </ul> <script> let ul = document.querySelectorAll('ul')[0] let aLi = document.querySelectorAll('li') $('ul').on('click','li',function(e){ console.log(e.target) // 被點擊的元素 console.log(e.currentTarget) // li console.log(e.currentTarget === this) // true }) </script> </body> </html>
當li中含有子元素的時候,e.target指的是觸發事件的元素,可能是span也可能是li,此時的e.currentTarget指的是selector那個參數,也就是本例中的li。如果省略selector參數,那么它和addEventListener中e.target和e.currentTarget是一致的。
事件目標階段
我們知道,在DOM事件流中分為幾個不同的階段,如圖
上述例子是事件冒泡階段,
e.currenttarget和
e.target是不相等的,但是在事件的目標階段,
e.currenttarget和
e.target是相等的。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JS Bin</title> </head> <body> <ul> <li>hello 1</li> <li>hello 2</li> <li>hello 3</li> <li>hello 4</li> </ul> <script> let ul = document.querySelectorAll('ul')[0] let aLi = document.querySelectorAll('li') for(let i=0;i<aLi.length;i++){ aLi[i].addEventListener('click',function(e){ let oLi1 = e.target let oLi2 = e.currentTarget console.log(oLi1) // li console.log(oLi2) // li console.og(oLi1===oLi2) // true }) } </script> </body> </html>
在本例中,事件的目標階段即li,由於e.currentTarget始終指向添加監聽事件的那個對象,即aLi[i],也就是HTML中的li,而e.target指向觸發事件監聽的那個對象,也是li,因此e.target和e.currentTarget相等,同時也和this相等。
總結
因此不必記什么時候e.currentTarget和e.target相等,什么時候不等,理解兩者的究竟指向的是誰即可。
e.target指向觸發事件監聽的對象。e.currentTarget指向添加監聽事件的對象。
參考
作者:plainnany
鏈接:https://www.jianshu.com/p/1dd668ccc97a
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。
