In this case, at the time you call console.log(e)
, there's a DOM element in the currentTarget property. But sometime later, that property is reset to null
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:
<body>
<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>
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 called event.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 the a
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 the e.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 between target and currentTarget. 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 listener directly attached to while 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.