简体   繁体   中英

How to get href of anchor when the event.target is HTMLImageElement?

I want to get the href of an anchor element when it is clicked. I am using the following javascript code:

document.addEventListener('click', function (event)
{
    event = event || window.event;
    var el = event.target || event.srcElement;

    if (el instanceof HTMLAnchorElement)
    {
        console.log(el.getAttribute('href'));
    }
}, true);

This works perfectly for an embedded anchor such as this:

<div><p><a href='link'></a></p><div>

But it doesn't work when I am working with an anchor and an image:

<div><a href='link'><img></a></div>

The event.target is returning the image instead of the anchor. The javascript code can be amended with the following if case to get around this:

document.addEventListener('click', function (event)
{
    event = event || window.event;
    var el = event.target || event.srcElement;

    if (el instanceof HTMLImageElement)
    {
        // Using parentNode to get the image element parent - the anchor element.
        console.log(el.parentNode.getAttribute('href'));
    }
    else if (el instanceof HTMLAnchorElement)
    {
        console.log(el.getAttribute('href'));
    }
}, true);

But this doesn't seem very elegant and I'm wondering if there is a better way.

!IMPORTANT! NOTE: Keep in mind, I have no access to an ID or class, or any other traditional identifier for that matter. All I know is that there will be an anchor clicked and I need to get its href. I don't even know where it will be, if it exists or will be created later.

EDIT: Please no jQuery or other javascript libraries.

Instead of looping all anchors in the DOM, lookup from the event.target element.
Using JavaScript's .closest() MDN Docs (PS: polyfill for IE )

 addEventListener('click', function (event) { event.preventDefault(); // Don't navigate! const anchor = event.target.closest("a"); // Find closest Anchor (or self) if (!anchor) return; // Not found. Exit here. console.log( anchor.getAttribute('href')); // Log to test });
 <a href="http://stackoverflow.com/a/29223576/383904"> <span> <img src="//placehold.it/200x60?text=Click+me"> </span> </a> <a href="http://stackoverflow.com/a/29223576/383904"> Or click me </a>

it basically works like jQuery's .closest() which does

Closest or Self (Find closest parent... else - target me!)

better depicted in the example above.

Rather than adding a global click handler, why not just target only anchor tags?

var anchors = document.getElementsByTagName("a");
for (var i = 0, length = anchors.length; i < length; i++) {
  var anchor = anchors[i];
  anchor.addEventListener('click', function() {
    // `this` refers to the anchor tag that's been clicked
    console.log(this.getAttribute('href'));
  }, true);
};

If you want to stick with the document-wide click handler then you could crawl upwards to determine if the thing clicked is-or-is-contained-within a link like so:

document.addEventListener('click', function(event) {
    event = event || window.event;
    var target = event.target || event.srcElement;

    while (target) {
      if (target instanceof HTMLAnchorElement) {
        console.log(target.getAttribute('href'));
        break;
      }

      target = target.parentNode;
    }
}, true);

This way at least you'd avoid writing brittle code that has to account for all of the possible types of anchor-children and nested structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM