谁能告诉我JavaScript事件中的currentTarget和target属性的确切区别,以及哪个属性在哪个场景中使用?
currentTarget
target
事件默认为泡沫。所以两者的区别是:
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监听它,并附加到结果:
1
target: 2 currentTarget: 1
因为在这种情况下:
2
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>
<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>
[object html段落][object HTMLDivElement]
< p >事件。目标是事件产生的节点, 而且 事件。相反,currentarget指向附加了当前事件监听器的节点。看到冒泡
这里我们点击了P标签,但是我们没有监听器在P上,而是在它的父元素div上。
对于泡沫的房地产为true的事件,它们会冒泡。
true
大多数事件都冒泡,除了几个,即焦点, 模糊, mouseenter, mouseleave,…
如果事件evt发生冒泡,则evt.currentTarget将更改为冒泡路径中的当前的目标,而evt.target将保持与触发事件的原始目标相同的值。
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会删除事件池。
因此,事件对象在处理程序中被刷新,可以安全地用于异步调用( codepen < / >)。
并不总是正确的。onClick事件的currentTarget在事件处理程序结束后是undefined。总之,如果您打算在同步调用之后使用事件属性,总是将在本地缓存它们。
onClick
undefined
从# EYZ0
注意: 从v17开始,e.persist()不做任何事情,因为SyntheticEvent
注意:
还有很多其他东西太长,不能粘贴在答案中,所以我总结了一下,做了这里有一篇博客文章。
Event.currentTarget是事件处理程序已归属的元素 attach ,而不是Event.target,它标识了on的元素 哪个事件发生了,哪个可能是它的后代.
Event.currentTarget
Event.target
来源:# EYZ0
target总是指向addEventListener前面的元素——它是事件发生的元素。 currentTarget告诉你-如果这是一个冒泡的事件-当前附加了事件监听器的元素(如果事件发生,它将触发事件处理程序)
addEventListener
有关示例,请参阅这CodePen。如果你打开开发工具并单击方块,你会看到首先div是目标和currentTarget,但是事件气泡上升到主元素-然后主元素变成了currentTarget,而div仍然是目标。注意,要发生冒泡,需要将事件侦听器附加到这两个元素。
这里有一个简单的场景来解释为什么需要它。假设你用下面的格式向用户显示了一些消息,但你也想让他们自由地关闭它们(除非你有特殊的精神障碍),所以这里有一些消息窗格:
[消息将在此窗格[x]]中显示]
当用户单击每个按钮上的[x]按钮时,必须删除整个对应的窗格。
下面是窗格的HTML代码:
<div class="pane"> A message will be here <span class="remove-button">[x]</span> </div>
用户点击[x],但是你想要删除这个窗格,所以:
如果你将点击事件监听器添加到窗格,点击“窗格上的所有地方”;会删除它,而不是只点击[x]按钮。
那么我们能做什么呢?我们可以用&;Bubbles up &;事件系统特点:
“无论是否存在任何事件处理程序,事件都会被引发并在DOM树中冒泡。”
在我们的示例中,这意味着即使我们将事件处理程序添加到窗格中,我们也能够捕获由单击[x]按钮引起的特定事件(因为事件会冒泡)。因此,在引发事件的位置和我们捕获并处理它的位置之间存在可以的区别。
它被升起的地方将在event.target中,而它被捕获的地方将在event.currentTarget中(我们正在目前中处理它)。所以:
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