最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - event.target of a jQuery click event returning the child of the clicked element - Stack Overflow

programmeradmin2浏览0评论

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 bee 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.

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 bee 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.

Share Improve this question asked Jan 30, 2020 at 8:11 SaraSara 451 silver badge10 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

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./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./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>

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/en-US/docs/Web/API/Event/currentTarget

Hope this was helpful.

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>

发布评论

评论列表(0)

  1. 暂无评论