javascript中currentTarget属性和target属性之间的确切区别是什么?

时间:2012-04-10 09:45:52

标签: javascript

有人可以告诉我Javascript事件中currentTargettarget属性与示例之间的确切区别,以及在哪种情况下使用哪个属性?

9 个答案:

答案 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)

对于 bubblestrue 的事件,它们会冒泡。

大多数事件都会冒泡,除了几个,即 focusblurmouseentermouseleave、...

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

Event's target types

值得注意的是,如果您的事件处理程序(冒泡事件的)是异步的并且处理程序使用 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 会删除 Event Pooling

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

↑并不总是正确的。事件处理程序完成后,onClick 事件的 currentTargetundefined。总之,如果您要在同步调用后使用它们,总是在本地缓存事件的属性。

来自react docs

<块引用>

注意:

从 v17 开始,e.persist() 不会做任何事情,因为 SyntheticEvent 不再汇集。

还有很多其他的东西太长无法粘贴在答案中,所以我总结并制作了a blog post here

答案 5 :(得分:3)

&#13;
&#13;
<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;
&#13;
&#13;

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

&#13;
&#13;
<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;
&#13;
&#13; 我们刚从P和表单标签中删除了onclick,现在当我们点击P标签时,我们只收到一条提醒:

  

[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