Reputation: 83
I have the HTML below:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div>
<section>
<a>first</a>
<a>second</a>
</section>
</div>
<section>
<a>third</a>
<a>fourth</a>
</section>
<section>
<div>
<a>fifth</a>
<a>sixth</a>
</div>
</section>
<script src="ex-2-a.js"></script>
<!--<script src="ex-2-b.js"></script>-->
</body>
</html>
I'm looking to add only one event listener to the whole document that would catch only 'a' tags that have a 'div' as ancestors. This means that if I click first, second, fifth and sixth I would get a message saying "cool".
Any ideas on that matter since there's no id and working with only tagnames?
Upvotes: 1
Views: 2365
Reputation: 83
Thanks to @Scott Marcus for helping out. I submitted the answer and it worked. I also found a new approach using .closest(). let me know your thoughts
document.addEventListener('click',(e)=>{
let currElm = e.target;
if (currElm.closest('div')) {
console.log(currElm);
}
});
Upvotes: 1
Reputation: 65796
Using "event delegation" (setting an event handler on an element high up in the DOM tree and allowing events from elements lower in the tree to bubble up and be caught), we can set up just one event handler at the body
level and then we can check the actual source of the bubbled event against a collection of elements that match your criteria.
See inline comments for more:
// Set the event listener at the <body> and wait for other
// events to bubble up to it.
document.body.addEventListener("click", function(evt){
// Get an array of all the <a> elements that are descendants of <div> elements
let matches = Array.prototype.slice.call(document.querySelectorAll("div a"));
// Test to see if array contains the one that was clicked
if(matches.includes(evt.target)){
console.log("You clicked an <a> that is a descendant of a <div>!");
}
});
<div>
<section>
<a>first</a>
<a>second</a>
</section>
</div>
<section>
<a>third</a>
<a>fourth</a>
</section>
<section>
<div>
<a>fifth</a>
<a>sixth</a>
</div>
</section>
Upvotes: 0