Reputation: 243
I'm trying to put a listener on every tag "a". Here the example: http://fiddle.jshell.net/w5unvaxt/
function callback(e) {
var e = window.e || e;
/*
if (e.target.tagName !== 'A')
return;
*/
alert('The link is: ' + e.target.href);
}
if (document.addEventListener){
document.addEventListener('click', function (event) {
event.preventDefault();
callback(event);
});
}else{
document.attachEvent('onclick', function (event) {
event.preventDefault();
callback(event);
});
}
<!-- Works -->
<a href="http://www.example.com">my text</a>
<!-- not works -->
<a href="http://www.example.com">
<div>my div</div>
</a>
The first example works good but not the second. How can I solve this issue?
Upvotes: 2
Views: 16953
Reputation: 4122
The reason your code doesn't work is because the target element being clicked is the div
not the a
. This means that e.target.href
is undefined
for the div
.
Using event delegation in plain JS is quite difficult. Just looking at the source code of a small library that accomplishes kinda what you want, I can see that it loops through the targets and if the target does not match the specified it assigns target
to target.parentNode
.
I would recommend using a small library like the ones I have linked (or event jQuery!).
You could use event delegation.
Event delegation allows you to avoid adding event listeners to specific nodes; instead, the event listener is added to one parent. That event listener analyzes bubbled events to find a match on child elements.
Here is an article on how event delegation works.
And the following is my example of how to use event delegation in plain JS.
// Get the parent DIV, add click listener...
document.body.addEventListener("click", function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
alert(e.target.innerText);
}
});
<a href="#">Link text</a>
This way you only have to attach on event listener to the parent.
Upvotes: 3