I have a jQuery click event on a hyperlink containing an image. Both the hyperlink and the image has seperate id
s. 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 Class
es 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 id
s. 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 Class
es instead of the function-based "class" I've used. It's irrelevant to my question.
3 Answers
Reset to default 6The 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>