Why I don't think it's a duplicate.
Hmm, I think that's slightly different to what I'm asking. I don't want to add a listener to all A tags, rather, substract an href attribute, if any, on a click event's target.
I'm trying to "Ajaxify" my whole site, so that when an user clicks ANY link contained within the page, a script sends the "url" or HREF
attribute (of the clicked element) to an Ajax function, which in return, renders the requested content (as indicated by the link clicked).
I need to find the HREF
attribute of the clicked element, if the element is a link. The problem here, is that many elements can be contained within an A tag (because of the way I've structured them), and e.target.href
doesn't necessarily always return an HREF
attribute.
Here is what I have so far:
function ajaxifyLinks(e) {
var target = e.target;
e.preventDefault();
while(!target.href) {
target = target.parentNode;
}
if(target.href) {
ajaxLoad(target.href);
}
}
document.body.addEventListener('click', ajaxifyLinks);
And here are examples of different "clickable" links that I have:
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
As you can see, this is why e.target.href
won't always return the HREF attribute, because you are actually clicking a "linked" span element, however, the browser does take you to the link. Why does this happen? And is there any way I can benefit from that behavior? (As in, extracting the location where the browser is taking you, even if you aren't clicking over an A tag).
I don't like my solution, because the while loop just keeps looking up the DOM tree, sometimes needlessly (when e.target isn't a link or contained by a link).
Thanks.
If the element clicked does not have an href, it searches it's parents for an element that has an href. Vanilla JS solution.
function findUpTag(el, attr) {
while (el.parentNode) {
el = el.parentNode;
if (el[attr]) {
return el;
}
}
return null;
}
document.body.onclick = function (event) {
event.preventDefault();
var href = event.target.href;
if (!href) {
var closest = findUpTag(event.target, 'href');
if (closest) {
href = closest.href;
}
}
document.getElementById('output').innerHTML = 'element clicked: ' + event.target.nodeName + '<br>closest href: ' + href;
};
a,
output {
display: block;
}
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
<output id="output"></output>