Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing clicks on all A tags using eventListener

I'm trying to come up with a solution that will allow me to know whenever an "A" tag (or any other tag within an "A" tag) is clicked.

For example:

<a href="#">Link 1</a>
<a href="#"><span>Link 2</span></a>
<a href="#"><img src="#">Link 3</img></a>

So far I have this:

<script>
document.getElementsByTagName("BODY")[0].addEventListener('click', function(e) {
if(e.target && e.target.tagName == "A") {
console.log(e.target.text); }
}, false);
</script>

This is returning the text for link 1, but not for links 2 and 3. I also do not want to get any text if someone clicks on span or img elements that dont have an anchor tag.

like image 538
frankbraga Avatar asked Mar 18 '23 22:03

frankbraga


1 Answers

Legacy Browsers

.target returns the element that was clicked on. In the case of link 2, this will always be the span tag; on a properly formed version of link 3 sometimes it would be the a tag, sometimes it would be the img tag depending where you click. In order to figure out if the .target is inside of an a tag you need to climb up the DOM tree using parentNode until you reach an a node or the document itself, which has a .parentNode of null.

var getParentAnchor = function (element) {
  while (element !== null) {
    if (element.tagName && element.tagName.toUpperCase() === "A") {
      return element;
    }
    element = element.parentNode;
  }
  return null;
};

document.querySelector("body").addEventListener('click', function(e) {
  var anchor = getParentAnchor(e.target);
  if(anchor !== null) {
    console.log(anchor.textContent);
  }
}, false);
<a href="#">Link 1</a>
<a href="#"><span>Link 2</span></a>
<a href="#"><img src="example.jpg">Link 3</a>
<div>
Non link text
</div>

The standard .textContent should be preffered over .text.

It's easier to use querySelector to grab the body, unless you need to support IE7 or less.

Modern Browsers

If you don't need to support older browsers like IE or Opera mini, the code can be simplified by using the Element.closest method. You can completely get rid of the getParentAnchor and replace it with a single .closest call, shortening the code quite a bit:

document.querySelector("body").addEventListener('click', function(e) {
  var anchor = e.target.closest('a');
  if(anchor !== null) {
    console.log(anchor.textContent);
  }
}, false);
<a href="#">Link 1</a>
<a href="#"><span>Link 2</span></a>
<a href="#"><img src="example.jpg">Link 3</a>
<div>
Non link text
</div>
like image 130
Useless Code Avatar answered Mar 29 '23 11:03

Useless Code