I am thinking of to add a javascript function to capture all the <a> click events inside a html page.
So I am adding a global function that governs all the <a> click events, but not adding onclick to each (neither using .onclick= nor attachEvent(onclick...) nor inline onclick=). I will leave each <a> as simple as <a href="someurl"> within the html without touching them.
I tried window.onclick = function (e) {...} but that just captures all the clicks How do I specify only the clicks on <a> and to extract the links inside <a> that is being clicked?
Restriction: I don't want to use any exra libraries like jQuery, just vanilla javascript.
211 Answers
Use event delegation:
document.addEventListener(`click`, e => { const origin = e.target.closest(`a`); if (origin) { console.clear(); console.log(`You clicked ${origin.href}`); } });<div> <a href="#l1">some link</a> <div><a href="#l2"><div><i>some other (nested) link</i></div></a></div> </div>[edit 2020/08/20] Modernized
0You can handle all click using window.onclick and then filter using event.target
Example as you asked:
<html> <head> <script type="text/javascript"> window.onclick = function(e) { alert(e.target);}; </script> </head> <body> <a href="">google</a> <a href="">yahoo</a> <a href="">facebook</a> </body> </html> 6window.onclick = function (e) { if (e.target.localName == 'a') { console.log('a tag clicked!'); } } 2your idea to delegate the event to the window and then check if the "event.target" is a link, is one way to go (better would be document.body). The trouble here is that it won't work if you click on a child node of your element. Think:
<a href="#"><b>I am bold</b></a> the target would be the <b> element, not the link. This means checking for e.target won't work. So, you would have to crawl up all the dom tree to check if the clicked element is a descendant of a <a> element.
Another method that requires less computation on every click, but costs more to initialize would be to get all <a> tags and attach your event in a loop:
var links = Array.prototype.slice.call( document.getElementsByTagName('a') ); var count = links.length; for(var i = 0; i < count; i++) { links[i].addEventListener('click', function(e) { //your code here }); } (PS: why do I convert the HTMLCollection to array? here's the answer.)
1You need to take into account that a link can be nested with other elements and want to traverse the tree back to the 'a' element. This works for me:
window.onclick = function(e) { var node = e.target; while (node != undefined && node.localName != 'a') { node = node.parentNode; } if (node != undefined) { console.log(node.href); /* Your link handler here */ return false; // stop handling the click } else { return true; // handle other clicks } } You can also try using this:
var forEach = Array.prototype.forEach; var links = document.getElementsByTagName('a'); forEach.call(links, function (link) { link.onclick = function () { console.log('Clicked'); } }); It works, I just tested!
Somewhere in comments you mentioned you want to get the 'href' value you can do that with this:
var forEach = Array.prototype.forEach; var links = document.getElementsByTagName('a'); forEach.call(links, function (link) { link.onclick = function () { console.log(link.href); //use link.href for the value } }); Try jQuery and
$('a').click(function(event) { *your code here* }); In this function you can extract href value in this way:
$(this).attr('href') 1Some accepted answers dont work with nested elements like: <a href="..."><font><u>link</u></font></a>
There is a basic solution for most cases:
var links = document.getElementsByTagName('a'); for(var i in links) { links[i].onclick = function(e){ e.preventDefault(); var href = this.href; // ... do what you need here. } } If anybody is looking for the typed version (TypeScript, using Kooilnc's answer), here it is:
document.addEventListener("click", (e: Event) => { if(!e.target) { return; } if(!(e.target instanceof Element)) { return; } const origin = e.target.closest("a"); if(!origin || !origin.href) { return; } console.log(`You clicked ${origin.href}`); }); I guess this simple code will work with jquery.
$("a").click(function(){ alert($(this).attr('href')); }); Without JQuery:
window.onclick = function(e) { if(e.target.localName=='a') alert(e.target); }; The above will produce the same result.
2Very simple :
document.getElementById("YOUR_ID").onclick = function (e) {...} The selector is what you want to select so lets say you have button called
<a href="#">Button1</a> The code to capure this is:
document.getElementById("button1").onclick = function (e) { alert('button1 clicked'); } Hope that helps.
1