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


当前回答

<时尚> 正文* { 保证金:10 px; 边框:1px纯蓝色; } > < /风格 <形式onclick = "警报(形式)“>形式 < div onclick = "警报(div)“> DIV < p onclick = "警报(“p”)“P > < / P > < / div > > < /形式

如果点击上面代码中的P标签,那么你会得到三个警报,如果你点击div标签,你会得到两个警报和一个警报,点击表单标签。 现在看下面的代码,

<时尚> 正文* { 保证金:10 px; 边框:1px纯蓝色; } > < /风格 < >脚本 函数有趣(事件){ 警报(事件。目标+ " " + event.currentTarget); } > < /脚本 < >形式 < div onclick = "乐趣(事件)“> DIV < p > p > < / p < / div > > < /形式 我们刚刚从P和form标签中删除了onclick,现在当我们点击P标签时,我们只得到一个警告:

[htmlparagraph片段][htmlvevement对象]

这里的事件。目标是[object html分段ement],而事件。curentTarget是[object HTMLDivElement]: 所以

事件。目标是事件产生的节点, 而且 事件。相反,currentarget指向附加了当前事件监听器的节点。知多见冒泡

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

其他回答

默认情况下,事件冒泡。所以两者的区别是:

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

一个实验:

document.addEventListener("click", (e) => {
  console.log(e.target, e.currentTarget);
});
document.querySelector("p").click();

输出:

<p></p>
#document

target (<p></p>)似乎是被点击的元素,而currentTarget (#document)是监听点击事件的元素。

<时尚> 正文* { 保证金:10 px; 边框:1px纯蓝色; } > < /风格 <形式onclick = "警报(形式)“>形式 < div onclick = "警报(div)“> DIV < p onclick = "警报(“p”)“P > < / P > < / div > > < /形式

如果点击上面代码中的P标签,那么你会得到三个警报,如果你点击div标签,你会得到两个警报和一个警报,点击表单标签。 现在看下面的代码,

<时尚> 正文* { 保证金:10 px; 边框:1px纯蓝色; } > < /风格 < >脚本 函数有趣(事件){ 警报(事件。目标+ " " + event.currentTarget); } > < /脚本 < >形式 < div onclick = "乐趣(事件)“> DIV < p > p > < / p < / div > > < /形式 我们刚刚从P和form标签中删除了onclick,现在当我们点击P标签时,我们只得到一个警告:

[htmlparagraph片段][htmlvevement对象]

这里的事件。目标是[object html分段ement],而事件。curentTarget是[object HTMLDivElement]: 所以

事件。目标是事件产生的节点, 而且 事件。相反,currentarget指向附加了当前事件监听器的节点。知多见冒泡

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

对于泡沫属性为真的事件,它们会冒泡。

大多数事件都冒泡,除了几个,即焦点,模糊,鼠标进入,鼠标离开,…

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

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

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

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

因此,事件对象在处理程序中被刷新,可以安全地用于异步调用(依赖于代码)。

并不总是正确的。onClick事件的currentTarget在事件处理程序结束后未定义。总之,如果要在同步调用之后使用事件的属性,请始终在本地缓存它们。

来自react文档

注意: 从v17开始,e.persist()不做任何事情,因为SyntheticEvent 不再被池化。

还有很多其他的东西太长了,不能贴在答案里,所以我总结了一下,在这里写了一篇博客。

事件。currentTarget是事件处理程序已经归属的元素 附加的,而不是事件。目标,它标识上的元素 哪个事件发生了,哪个可能是它的后代。

来源:中数

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

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