Solution 1 :

The event.target will always be the element that dispatched the event. If you click on an element inside a container, then no matter what element the listener is attached to, the event.target will be the element inside the container.

If you want a reference to the element the listener is attached to, use this or event.currentTarget:

$("#menu a").click(function() {
  console.log(this.id);
  // pages[linkToPageId[this.id]].loadPage();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="menuContainer">
  <ul id="menu">
    <li>
      <a id="home"><img id="logo" src="img/logo.png" alt="logo"></a>
    </li>
    <li><a id="about">Om oss</a></li>
    <li><a id="concept">Konsept</a></li>
    <li><a id="history">Data</a></li>
    <li><a id="store">Butikk</a></li>
  </ul>
</div>
<div id="frontpage"></div>
<div id="content"></div>
$("#menu a").click(function() {
  console.log(event.currentTarget.id);
  // pages[linkToPageId[event.currentTarget]].loadPage();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="menuContainer">
  <ul id="menu">
    <li>
      <a id="home"><img id="logo" src="img/logo.png" alt="logo"></a>
    </li>
    <li><a id="about">Om oss</a></li>
    <li><a id="concept">Konsept</a></li>
    <li><a id="history">Data</a></li>
    <li><a id="store">Butikk</a></li>
  </ul>
</div>
<div id="frontpage"></div>
<div id="content"></div>

Solution 2 :

you use event.currentTarget which points to the element that you attached the listener. It does not change as the event bubbles.

https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

Hope this was helpful.

Solution 3 :

There is a CSS tricks that will ignore hover and click events for the element on which is set the rule:

#menu a img {
    pointer-events: none;
}

This rule will cancel your :hover rules on that element (and children because of the cascading beauty of CSS).

document
    .querySelectorAll("#menu a")
    .forEach(
        (element) => element.addEventListener(
            "click", 
            (event) => document.querySelector("#click-target").textContent = event.target.outerHTML
        )
    );
#menu a span.icon {
    pointer-events: none;
}
#menu a span:hover {
    color: #F0F;
    font-weight: 700;
}
<p>Try me by clicking on links or on the "checkbox" icons.</p>

<ul id="menu">
  <li><a href="#"><span class="icon">☑ </span> pointer-events: none</a>
  <li><a href="#"><span>☐ </span> No pointer-events rule</a>
</ul>

<div id="click-target"></div>

Problem :

I have a jQuery click event on a hyperlink containing an image. Both the hyperlink and the image has seperate ids. I’d expect that when I click the hyperlink, the code event.target.id inside the event handler would return the hyperlink id as the event is tied to the hyperlink, but it returns the image id. Why is that? Is there any way to always make the element tied to the event become the event.target?

HTML:

<div id="menuContainer">
    <ul id="menu">
        <li><a id="home"><img id="logo" src="img/logo.png" alt="logo"></a></li>
        <li><a id="about">Om oss</a></li>
        <li><a id="concept">Konsept</a></li>
        <li><a id="history">Data</a></li>
        <li><a id="store">Butikk</a></li>
    </ul>
</div>
<div id="frontpage"></div>
<div id="content"></div>

JS:

function Page(pageId, linkId, file, backgroundImg, showPage){
    this.id = pageId;
    this.link = linkId;
    this.content = file;
    this.img = backgroundImg;
    this.show = showPage;

    this.loadPage = function() {
        if (this.show && $cont.is(":hidden")) $cont.show();
        else if (!this.show && $cont.is(":visible")) $cont.hide();
        if (this.content != "") $cont.load(this.content);
        else $cont.html("");
        $("#frontpage").css("backgroundImage", "url(img/" + this.img + ")");
    }
}

var pages = [];
var linkToPageId = {};

function addPage(linkId, file, backgroundImg, showPage = true) {
    var pageId = pages.length;
    var newPage = new Page(pageId, linkId, file, backgroundImg, showPage);
    pages.push(newPage);
    linkToPageId[linkId] = pageId;
}

addPage("home", "", "frontpage.jpg", false);

$("#menu a").click(function(event){
    console.log(event.target.id);
    pages[linkToPageId[event.target.id]].loadPage();
});

PS. I know this can be quickfixed by giving changing the linkId of this specific Page object to “logo” instead of “home”, but it kinda spaghettifies the code. I would like to see if there’s any other option first.

PSS. I also know JS has actual Classes instead of the function-based “class” I’ve used. It’s irrelevant to my question.

Comments

Comment posted by Pinke Helga

Your wording is misleading. Actually

By