I need to capture an anchor node with an image inside using event delegation.
document.addEventListener(
'click',
function(event) {
console.log(event.target);
return true;
},
false
);
<a href="#" class="link">
<img src="http://placehold.it/100x100" alt="">
</a>
event.target is always img.
How can check if the click was made on a node with class .link?
UPDATE: to be clear here is an example with jQuery
When I use jQuery.on() there is a
node in this
property in callback fucntion, not img
node. With pure JS I can determine initial target only.
You can check if an element has a class by calling:
element.classList.contains('link');
What you want right now is to do something when an <img>
within an <a class="link">
is clicked. To determine if the clicked <img>
has a parent <a class="link">
we must traverse up its parent tree and check.
This is very similar behavior as the jQuery example you have, i.e.
$('body').on('click', '.link', callback)
except the jQuery matches a whole query, not just a class.
Here's how you could do this:
// function to determine if the element has the link class
const hasLinkClass = element => element
? element.classList && element.classList.contains('link')
: false;
// function that accepts an event handler and returns
// a wrapper function arround it.
// The wrapper is called it if the passed in event
// object contains as its target an <img> with a parent
// with .link class
function filterImagesWithinLinks(handler) {
return function(event) {
let elem = event.target;
// ignore clicks that are not on an image (it might be better to be more specific here)
if (elem.tagName === 'IMG') {
// filter until we find the parent with .link class
while (elem && !hasLinkClass(elem)) {
elem = elem.parentNode;
}
// if a parent with .link class was found,
// call the original handler and set its `this`
// to the parent.
if (elem) {
handler.call(elem, event);
}
}
};
}
// function handler that fires when
// an <img> that has a parent with
// class 'link' was clicked
function handler(event) {
console.log('target : ', event.target);
console.log('this : ', this);
}
document.addEventListener(
'click',
filterImagesWithinLinks(handler),
false
);
a.link {
display: block;
padding: 10px;
background: #018bbc;
}
.middle {
background: salmon;
padding: 10px;
text-align: center;
}
<a href="#" class="link">
<p class="middle">
<img src="http://placehold.it/100x100" alt="" />
</p>
</a>