有人可以告诉我Javascript事件中currentTarget
和target
属性与示例之间的确切区别,以及在哪种情况下使用哪个属性?
答案 0 :(得分:230)
基本上,默认为events bubble,因此两者之间的区别是:
target
是触发事件的元素(例如,用户点击了)currentTarget
是事件侦听器附加到的元素。请参阅此blog post的简单说明。
答案 1 :(得分:45)
target
=触发事件的元素。
currentTarget
=侦听事件的元素。
答案 2 :(得分:13)
最小可运行示例
window.onload = function() {
var resultElem = document.getElementById('result')
document.getElementById('1').addEventListener(
'click',
function(event) {
resultElem.innerHTML += ('<div>target: ' + event.target.id + '</div>')
resultElem.innerHTML += ('<div>currentTarget: ' + event.currentTarget.id + '</div>')
},
false
)
document.getElementById('2').dispatchEvent(
new Event('click', { bubbles:true }))
}
<div id="1">1 click me
<div id="2">2 click me as well</div>
</div>
<div id="result">
<div>result:</div>
</div>
如果您点击:
2 click me as well
然后1
收听它,并附加到结果:
target: 2
currentTarget: 1
因为在那种情况下:
2
是发起事件的元素1
是听取事件的元素如果您点击:
1 click me
相反,结果是:
target: 1
currentTarget: 1
在Chromium 71上测试。
答案 3 :(得分:10)
如果这不是坚持,请尝试:
currentTarget
中的当前指的是现在。它是最近发现从其他地方冒出来的事件的目标。
答案 4 :(得分:8)
对于 bubbles 为 true
的事件,它们会冒泡。
大多数事件都会冒泡,除了几个,即 focus、blur、mouseenter、mouseleave、...
如果事件 evt
冒泡,则 evt.currentTarget
在其冒泡路径中更改为当前目标,而 evt.target
保持与触发事件的原始目标。
值得注意的是,如果您的事件处理程序(冒泡事件的)是异步的并且处理程序使用 evt.currentTarget
。 currentTarget
应该在本地缓存,因为事件对象在冒泡链 (codepen) 中被重用。
const clickHandler = evt => {
const {currentTarget} = evt // cache property locally
setTimeout(() => {
console.log('evt.currentTarget changed', evt.currentTarget !== currentTarget)
}, 3000)
}
如果您使用 React,从 v17 开始,react 会删除 Event Pooling。
因此,事件对象在处理程序中刷新并且可以安全地用于异步调用 (codepen)。
↑并不总是正确的。事件处理程序完成后,onClick
事件的 currentTarget
为 undefined
。总之,如果您要在同步调用后使用它们,总是在本地缓存事件的属性。
注意:
从 v17 开始,e.persist() 不会做任何事情,因为 SyntheticEvent 不再汇集。
还有很多其他的东西太长无法粘贴在答案中,所以我总结并制作了a blog post here。
答案 5 :(得分:3)
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
&#13;
如果点击上面代码中的P标签,那么您将获得三个警报,如果您单击div标签,您将在单击表单标签时获得两个警报和一个警报。 现在看下面的代码,
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<script>
function fun(event){
alert(event.target+" "+event.currentTarget);
}
</script>
<form>FORM
<div onclick="fun(event)">DIV
<p>P</p>
</div>
</form>
&#13;
[object HTMLParagraphElement] [object HTMLDivElement]
这里event.target是[object HTMLParagraphElement],event.curentTarget是[object HTMLDivElement]: 所以
event.target是发起事件的节点, 和 event.currentTarget,相反,指的是附加了当前事件监听器的节点。要了解更多see bubbling
在这里我们点击了P标签,但我们没有P上的监听器,但是它的父元素div。
答案 6 :(得分:2)
Event.currentTarget
是事件处理程序所处理的 元素
附加,而不是Event.target
,它标识了元素
哪个事件发生了,哪个可能是它的后代。
来源:MDN
target
总是指 addEventListener
前面的元素 - 它是事件发生的元素。
currentTarget
告诉您 - 如果这是一个冒泡事件 - 当前附加了事件侦听器的元素(如果事件发生,它将触发事件处理程序)。
示例:假设您有 <main><div></div></main>
和 div.addEventListener('click', handleClick)
。如果点击 div
,事件处理程序将首先触发 div
- target
- 但事件会冒泡到 main
,所以 main
最终成为 currentTarget
。
答案 7 :(得分:1)
event.target 是发起事件的节点,即。无论您在何处放置事件监听器(在段落或跨度上),event.target都指节点(用户单击的位置)。
相反,event.currentTarget 指的是附加了当前事件侦听器的节点。 IE浏览器。如果我们将事件监听器附加到段节点上,则event.currentTarget引用段落,而event.target仍然引用span。 注意:如果我们在body上也有一个事件监听器,那么对于这个事件监听器,event.currentTarget引用body(即,每当事件冒泡一个节点时,作为event-listerners的输入提供的事件都会更新。)< / p>
答案 8 :(得分:0)
这里有一个简单的场景来解释为什么需要它。假设您使用以下格式向用户显示了一些消息,但您还希望让他们可以自由关闭它们(除非您有特殊的精神障碍),因此这里有一些消息窗格:
[ 此窗格中将显示一条消息 [x] ]
[ 此窗格中将显示一条消息 [x] ]
[ 此窗格中将显示一条消息 [x] ]
并且当用户点击每个面板上的 [x] 按钮时,必须删除整个相应的窗格。
这是窗格的 HTML 代码:
<div class="pane">
A message will be here
<span class="remove-button">[x]</span>
</div>
现在您想在哪里添加点击事件侦听器?用户点击了[x],但您想移除窗格,因此:
如果您将点击事件侦听器添加到 [x],那么您必须在 DOM 上找到它的父级并将其删除...这是可能的 em> 但丑陋且“依赖 DOM”。
如果您将单击事件侦听器添加到窗格中,单击“窗格上的任何地方”都会将其删除,而不仅仅是单击其 [x] 按钮。
那我们能做什么?我们可以使用事件系统的“Bubbles Up”功能:
<块引用>“无论是否存在任何事件处理程序,都会引发事件并向上冒泡 DOM 树。”
在我们的示例中,这意味着即使我们将事件处理程序添加到窗格中,我们也将能够捕获由 [x] 按钮点击引起的事件(因为事件会冒泡)。因此,在引发事件的位置与我们捕获和处理它的位置之间可能有所不同。
它被引发的地方将在 event.target
中,它被捕获的地方将在 event.currentTarget
中(我们当前正在处理它)。所以:
let panes = document.getElementsByClassName("pane");
for(let pane of panes){
pane.addEventListener('click', hndlr);
}
function hndlr(e){
if(e.target.classList.contains('remove-button')){
e.currentTarget.remove();
}
}
(此示例归功于网站 JavaScript.info)