在JavaScript中,currentTarget属性和target属性的确切区别是什么

谁能告诉我JavaScript事件中的currentTargettarget属性的确切区别,以及哪个属性在哪个场景中使用?

166455 次浏览

事件默认为泡沫。所以两者的区别是:

  • target是触发事件的元素(例如,用户点击)
  • currentTarget是事件监听器附加的元素。

target =触发事件的元素。

currentTarget =具有事件监听器的元素。

如果这还不行,试试这个:

currentTarget中的当前的指的是现在。这是最新的目标,捕捉到从其他地方冒出来的事件。

最小可运行示例

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

铬71测试。

event.target是事件产生的节点。无论您将事件侦听器放置在何处(在段落或span上),事件。目标指的是节点(用户单击的地方)。

event.currentTarget,相反,指的是当前事件监听器所附加的节点。Ie。如果将事件监听器附加在段落节点上,则event。currentarget指向段落while事件。目标仍然指向span。 注意:如果我们在body上也有一个事件监听器,那么对于这个事件监听器,事件。currentTarget指的是body(即。每次事件冒泡一个节点时,作为事件监听器输入的事件将被更新)

<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>

如果点击上面代码中的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>
我们刚刚从P和form标签中删除了onclick,现在当我们点击P标签时,我们只得到一个警告:

[object html段落][object HTMLDivElement]

< p >这事件。目标是[object html分段ement],而事件。curentTarget是[object HTMLDivElement]: 所以< / p >
< p >事件。目标是事件产生的节点, 而且 事件。相反,currentarget指向附加了当前事件监听器的节点。看到冒泡

这里我们点击了P标签,但是我们没有监听器在P上,而是在它的父元素div上。

对于泡沫的房地产true的事件,它们会冒泡。

大多数事件都冒泡,除了几个,即焦点模糊mouseentermouseleave,…

如果事件evt发生冒泡,则evt.currentTarget将更改为冒泡路径中的当前的目标,而evt.target将保持与触发事件的原始目标相同的值。

事件的目标类型

值得注意的是,如果您的事件处理程序(冒泡事件)是异步的,并且处理程序使用evt.currentTargetcurrentTarget应该在本地缓存,因为事件对象在冒泡链(codepen)中被重用。

const clickHandler = evt => {
const {currentTarget} = evt // cache property locally
setTimeout(() => {
console.log('evt.currentTarget changed', evt.currentTarget !== currentTarget)
}, 3000)
}

如果你使用React,从v17开始,React会删除事件池

因此,事件对象在处理程序中被刷新,可以安全地用于异步调用( codepen < / >)。

并不总是正确的。onClick事件的currentTarget在事件处理程序结束后是undefined。总之,如果您打算在同步调用之后使用事件属性,总是将在本地缓存它们。

从# EYZ0

注意:

从v17开始,e.persist()不做任何事情,因为SyntheticEvent

还有很多其他东西太长,不能粘贴在答案中,所以我总结了一下,做了这里有一篇博客文章

Event.currentTarget是事件处理程序已归属的元素 attach ,而不是Event.target,它标识了on的元素 哪个事件发生了,哪个可能是它的后代.

来源:# EYZ0

target总是指向addEventListener前面的元素——它是事件发生的元素。 currentTarget告诉你-如果这是一个冒泡的事件-当前附加了事件监听器的元素(如果事件发生,它将触发事件处理程序)

有关示例,请参阅这CodePen。如果你打开开发工具并单击方块,你会看到首先div是目标和currentTarget,但是事件气泡上升到主元素-然后主元素变成了currentTarget,而div仍然是目标。注意,要发生冒泡,需要将事件侦听器附加到这两个元素。

这里有一个简单的场景来解释为什么需要它。假设你用下面的格式向用户显示了一些消息,但你也想让他们自由地关闭它们(除非你有特殊的精神障碍),所以这里有一些消息窗格:

[消息将在此窗格[x]]中显示]

[消息将在此窗格[x]]中显示]

[消息将在此窗格[x]]中显示]

当用户单击每个按钮上的[x]按钮时,必须删除整个对应的窗格。

下面是窗格的HTML代码:

<div class="pane">
A message will be here
<span class="remove-button">[x]</span>
</div>

用户点击[x],但是你想要删除这个窗格,所以:

  • 如果你将点击事件监听器添加到[x]中,那么你将不得不在DOM中找到它的父元素并删除它…这是可能的,但丑陋和“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网站)

一个小实验

function aaa
({target, currentTarget})
{console.log({target, currentTarget})};
document.addEventListener("click", aaa);
document.querySelector("p").click();
< p >定义 VM353:1
{target: p, currentarget: document}

. {target: p, currentarget: document