細說event.currentTarget & event.target的不同使用

細說event.currentTarget & event.target的不同使用

dom event簡介

Event介面表示在DOM中發生的任何事件; 一些是使用者生成的(例如滑鼠或鍵盤事件),而其他由API生成(例如指示動畫已經完成執行的事件,視訊已被暫停等等)。事件新增有以下幾個方法:

EventTarget.addEventListener
注意: Internet Explorer 6-8 並不支援這個方法,而是提供了類似的 element.attachEvent API 。如果要進行跨瀏覽器使用,請考慮使用有效的JavaScript 庫。

html的屬性新增 <button onclick=”alert(‘Hello world!’)”>
myButton.onclick = function(event){alert(‘Hello world’);};

事件新增目標就是EventTarget,也是註冊事件的監聽者。有的時候註冊事件的監聽者並不是事件的觸發者,實際事件的觸發者是event.target,

EventTarget事件目標

EventTarget 是一個由可以接收事件的物件實現的介面,並且可以為它們建立偵聽器。

Element,document 和 window 是最常見的事件目標,但是其他物件也可以是事件目標,比如XMLHttpRequest,AudioNode,AudioContext 等等。EventTarget例項主要需要實現下面三個方法:

EventTarget.addEventListener()
在EventTarget上註冊特定事件型別的事件處理程式。
EventTarget.removeEventListener()
EventTarget中刪除事件偵聽器。
EventTarget.dispatchEvent()
將事件分派到此EventTarget。

不少情況下,EventTarget就是註冊的事件的監聽者;

event例項

有許多型別的事件,其中一些使用基於主要事件介面的其他介面。事件本身包含所有事件通用的屬性和方法。在新增註冊事件的時候,事件響應一般是一個函式,而函式的第一個引數就是event,一個真實的事件物件的列印如下:

altKey:false
bubbles:true
button:0
buttons:0
cancelBubble:false
cancelable:true
clientX:30
clientY:62
composed:true
ctrlKey:false
currentTarget:button#myBtn
defaultPrevented:false
detail:1
eventPhase:0
fromElement:null
isTrusted:true
layerX:30
layerY:62
metaKey:false
movementX:0
movementY:0
offsetX:20
offsetY:6
pageX:30
pageY:62
path:(5) [button#myBtn, body, html, document, Window]
relatedTarget:null
returnValue:true
screenX:2377
screenY:320
shiftKey:false
sourceCapabilities:InputDeviceCapabilities {firesTouchEvents: false}
srcElement:button#myBtn
target:button#myBtn
timeStamp:658.445
toElement:button#myBtn
type:"click"
view:Window {frames: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
which:1
x:30
y:62
__proto__:MouseEvent

通過檢視w3c給出的event flow【https://www.w3.org/TR/DOM-Lev…】可以發現,由於事件捕獲和事件冒泡的存在,很多時候註冊的事件監聽者【event.currentTarget】並不是事件的觸發者【event.target】,大部分時候事件可能是由子元素觸發的,但是在捕獲、冒泡的過程中被父級元素的事件監聽器獲取到了,註冊監聽事件的父級元素就是這種情況下event.currentTarget,而事件觸發者也就是子元素就是event.target;

文字說來總是同步;可以看例項:

<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
<p>該例項使用 addEventListener() 方法在按鈕中新增點選事件。 </p>
<button id="myBtn">點我</button>
<p id="demo"></p>
<script>
var btn = document.getElementById("myBtn");
btn.addEventListener("click", function displayDate1(e)
{
console.log('按鈕註冊點選事件');
console.log(e.currentTarget);
console.log(e.target);
}
);
document.body.addEventListener("click", function displayDate1(e)
{
console.log('body註冊點選事件');
console.log(e.currentTarget);
console.log(e.target);
}
);
</script>
</body>
</html>

可以看到輸出如下:

具體的說就是event.currentTarget是註冊事件時所指向的元素,而event.target是響應事件的最小子元素,也就是最深層級的觸發事件的元素,需要開發者合理使用。
可以分情況使用:

event.currentTarget在註冊事件時如果希望獲取事件監聽者的相關屬性資料而不是出發事件的子元素的一些屬性或者資料的話,可以使用。
event.target適合監聽者是自身的時候,所以很多可點選的元素都沒有孩子元素。

注意:很多時候我們需要做區域點選響應,這樣的話需要注意你點選時需要操作的資料,因為觸發事件的元素是不確定的,但是可以考慮把資料放在監聽者的屬性中,這樣使用event.currentTarget來獲取詩句就是可靠地行為