Это потому, что событие click
пузырей , а e.target
- это элемент, на который было нацелено событие (это тот же элемент, который был фактически нажат на каждом уровне).Поэтому, когда вы щелкаете элемент a
, это происходит:
- Обработчик на
a
переключает класс на e.target
(элемент a
) - Щелчокпузыри к
p
, и обработчик на p
переключает класс на e.target
(элемент a
) - Клик на пузырях к
div
, а обработчик на div
переключает класс на e.target
(элемент a
) - Клик пузырится на
main
, а обработчик на main
переключает класс на e.target
(* 1029)* element)
Переключение чего-либо четное число раз возвращает вас к тому, с чего вы начали.: -)
Если бы на каждом уровне вы хотели ссылаться на элемент, к которому вы прикрепили обработчик, а не на элемент, на который было нацелено событие, вы бы использовали this
или e.currentTarget
.
Это может помочь прояснить ситуацию:
function setGold(event) {
event.target.classList.toggle("gold");
console.log("event.target.tagName = " + event.target.tagName);
console.log("event.currentTarget.tagName = " + event.currentTarget.tagName);
console.log("this.tagName = " + this.tagName);
}
function setup() {
document.getElementsByTagName("a")[0].addEventListener("click", setGold);
document.getElementsByTagName("p")[0].addEventListener("click", setGold);
document.getElementsByTagName("div")[0].addEventListener("click", setGold);
document.getElementsByTagName("main")[0].addEventListener("click", setGold);
}
window.addEventListener("load", setup);
main {
height: 500px;
width: 900px;
background-color: black;}
div.x (.as-console) {
height: 400px;
width: 700px;
background-color: dimgray;}
p.x {
height: 300px;
width: 500px;
background-color: darkgray;}
a.x {
height: 200px;
width: 300px;
background-color: lightgray;}
.gold {
background-color: gold;}
<main>
<div class="x">
<p class="x">
<a class="x">I'm an a-element.</a>
</p>
</div>
</main>
(Причина, по которой я добавил классы в ваши элементы и CSS, заключается в том, что в противном случае ваш CSS повлиял на консоль внутри фрагмента.)
Если ваша цель состоит в том, чтобы переключить просто элемент, по которому щелкнули, я бы воспользовался тем, что click
всплывает и использует только один обработчик для main
, имея его, переключается e.target
класс:
function setGold(event) {
event.target.classList.toggle("gold");
}
function setup() {
document.getElementsByTagName("main")[0].addEventListener("click", setGold);
}
function setGold(event) {
event.target.classList.toggle("gold");
}
function setup() {
document.getElementsByTagName("main")[0].addEventListener("click", setGold);
}
window.addEventListener("load", setup);
main {
height: 500px;
width: 900px;
background-color: black;}
div (.as-console) {
height: 400px;
width: 700px;
background-color: dimgray;}
p {
height: 300px;
width: 500px;
background-color: darkgray;}
a {
height: 200px;
width: 300px;
background-color: lightgray;}
.gold {
background-color: gold;}
<main>
<div>
<p>
<a>I'm an a-element.</a>
</p>
</div>
</main>
Если вы хотите отфильтровать это для переключения только main
, div
, p
и a
, но не (скажем,) span
, вы можете использовать Element#matches
, чтобы увидеть, соответствует ли элемент селектору CSS:
function setGold(event) {
if (event.target.matches("a, p, div, main")) {
event.target.classList.toggle("gold");
}
}
function setGold(event) {
if (event.target.matches("a, p, div, main")) {
event.target.classList.toggle("gold");
}
}
function setup() {
document.getElementsByTagName("main")[0].addEventListener("click", setGold);
}
window.addEventListener("load", setup);
main {
height: 500px;
width: 900px;
background-color: black;}
div (.as-console) {
height: 400px;
width: 700px;
background-color: dimgray;}
p {
height: 300px;
width: 500px;
background-color: darkgray;}
a {
height: 200px;
width: 300px;
background-color: lightgray;}
.gold {
background-color: gold;}
<main>
<div>
<p>
<a>I'm an a-element.</a>
<span>I'm a span, I don't toggle</span>
</p>
</div>
</main>
Примечание: событие load
происходит очень в конце цикла загрузки страницы и почти никогдаправильное место для настройки обработчиков кликов на странице.Вместо этого поместите теги script
в конце body
, непосредственно перед закрывающим тегом </body>
, и немедленно выполните настройку.Все элементы, определенные HTML-кодом над тегом, будут существовать в этой точке.Подробнее в Руководства YUI .