Почему только каждый другой HTML-элемент реагирует на «щелчок»? - PullRequest
0 голосов
/ 26 мая 2018

Очень просто - как реакция на «щелчок» по элементу, его класс должен переключаться.Работает, пока зарегистрирован только один обработчик событий.Если зарегистрировать более одного для других элементов, то только каждый другой элемент получит изменение своего класса.У меня есть чувство, что это связано с бурлящим событием, но этого недостаточно.Я хотел бы знать, почему это происходит и как я могу это контролировать.Вот что я получил:

HTML

<body>
<main>
    <div>
        <p>
        <a>I'm an a-element.</a>
        </p>
    </div>    
</main>     
</body>

CSS

main {
    height: 500px;
    width: 900px;
    background-color: black;}

div {
    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;}

JS

function setGold(event) {
    event.target.classList.toggle("gold");
}

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);

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Использование event.stopPropagation();

function setGold(event) {
    event.stopPropagation();
    event.target.classList.toggle("gold");
}

Проверьте это для получения дополнительной справки https://www.w3schools.com/jsref/event_stoppropagation.asp

0 голосов
/ 26 мая 2018

Это потому, что событие 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...