原文:/@florenceliang/javascript-event-delegation-and-event-target-vs-event-currenttarget-c9680c3a46d1
In this case, at the time you callconsole.log(e)
, there's a DOM element in the currentTarget property. But sometime later, that property is reset tonull
for some reason. When you expand the event object, that's what you see.
你的情况是,当调用console.log(e)
时,currentTarget属性是有值的,但是过后这个值就被重置为null
了。所以当你展开事件对象,看到的就是null
。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title><style type="text/css">#wrapDiv,#innerP,#textSpan {margin: 5px;padding: 5px;box-sizing: border-box;cursor: default;}#wrapDiv {width: 300px;height: 300px;border: indianred 3px solid;}#innerP {width: 200px;height: 200px;border: hotpink 3px solid;}#textSpan {display: block;width: 100px;height: 100px;border: orange 3px solid;}</style></head><body><div id="wrapDiv">wrapDiv<p id="innerP">innerP<span id="textSpan">textSpan</span></p></div><script>var div = document.getElementById('wrapDiv');var p = document.getElementById('innerP');var span = document.getElementById('textSpan');div.onclick = function(ev){console.log(ev); //console.log("target:", ev.target);console.log("currentTarget:", ev.currentTarget);}</script></body></html>
-----------------------------------------------
Event delegation is a popular methodology in JavaScript. It allows us to add an event listener to one parent, and avoid to add many event listeners to specific nodes. We can demonstrate this technique with simple example.
Let’s say we have a list with thousands of items:
<div id="container"> <ul id="list"> <li><a href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 3</a></li> <li><a href="#">Item 4</a></li> .................................. <li><a href="#">Item 1000</a></li> </ul> </div> </body><body>
With such number of items, it would be a nightmare to loop through every <a> element on the page, adding an event listener one after one. Moreover, it may “freeze” the page when JavaScript is trying to create them all.
So here comes the event delegation: When the event bubbles up to the body element, we can check the element that triggered the event, using the event object’s target property.
document.addEventListener("click", function(e) {
if(e.target && e.target.nodeName == "A") {
console.log("List item ", e.target.textContent, " was clicked!");
}
});
// When we click the 2nd item, the page prints out:
"List item Item 2 was clicked!"
target vs. currentTarget
Since we already talked about the event.target property, there is another property calledevent.currentTarget
in JavaScript event. It can be very confused by just reading about them on JavaScript documentation.
As we’ve seen from the last example, when we clicked thea
element,click
event bubbles up to <body> node of the document like below:
<a> → <li> → <ul> → <div> → <body>
Let’s add one more line of code and prints out what thee.currentTarget
is from the example we used above:
document.addEventListener(“click”, function(e) {
if(e.target && e.target.nodeName == “A”) {
console.log(“List item “, e.target.textContent, “ was clicked!”); // "List item Item 2 was clicked!"
}
console.log(e.currentTarget); // #document
});
It prints out “document” since we attached current event listener to the document while e.target refers to <a> which we clicked.
We can also look at one more example to see the differences betweentargetandcurrentTarget. This time, we add the event listener to the <ul>:
document.getElementById(“list”).addEventListener(“click”, function(e) {
console.log(e.currentTarget); //<ul><li>...</li><ul>
console.log(e.target); //<a href="#">Item 2</a>
);
Again, the currentTarget refers to the element that the event listenerdirectly attached towhile the target still refers to the specific <a> we clicked.
With these two properties target and currentTarget, we can easily manipulate the node when the event gets triggered, as well as the node the event is attached to.