Event.target неожиданно становится документом в функции прослушивателя связанных событий - PullRequest
2 голосов
/ 10 апреля 2020

Я хочу знать, выбрал ли пользователь размер перед покупкой одежды,
, поэтому я прикрепил прослушиватель событий к его родительскому контейнеру, области выбора.

Карта продукта с плитками селектора

Область выбора HTML Разметка

Если я передаю связанную функцию в качестве аргумента слушателю события,
event.target становится документом объект при щелчке.

if(selectionArea) {
  selectionArea.addEventListener("click", removeWarningStyles.bind(null, event, sizeTiles,warning));
}


Метод удаления стилей предупреждения:

function removeWarningStyles( event, sizeTiles, warning) {

    if(event.target.matches(".size-tile")) { // This becomes the document object. Why?
        for(let tile of  sizeTiles) {
            if(tile.classList.contains("size-tile--not-properly-chosen")) {
                tile.classList.toggle("size-tile--not-properly-chosen");

            }
        }
        warning.style.visibility = "hidden";
        warning.style.opacity = "0";
    }
}


Я даже пытался связать event.target и event.currentTarget , но все равно не работает.



Если я напишу анонимную функцию непосредственно в обработчик,
она будет работать отлично. Но почему?

if(selectionArea) {
   selectionArea.addEventListener("click", (event) => {

      if(event.target.classList.contains("size-tile")) { //becomes size-tile element correctly

        for(let tile of  sizeTiles) {
            if(tile.classList.contains("size-tile--not-properly-chosen")) {
               tile.classList.toggle("size-tile--not-properly-chosen");

           }
        }
        warning.style.visibility = "hidden";
        warning.style.opacity = "0";
     }
 });
}

1 Ответ

1 голос
/ 10 апреля 2020

Вы передаете event не так, как объект Event передается вашему EventListener, а как аргумент bind, который в любом случае бесполезен в этом случае, потому что вы привязываетесь к глобальному контексту, а ваша функция не содержит Ключевое слово this.

selectionArea.addEventListener("click", removeWarningStyles.bind(null, event, sizeTiles,warning));

Должно быть действительно

selectionArea.addEventListener('click', e=>{
  removeWarningStyles(e, sizeTiles, warning);
});

На самом деле, я хотел бы сделать

selectionArea.onclick = e=>{
  removeWarningStyles(e, sizeTiles, warning);
}

, потому что это проще удалить или перезаписать событие .

PS

Помните, что only Объект события передается в качестве аргумента функции eventListener, а контекст this объекта Функция eventListener - это Объект, к которому, как обычно, принадлежит метод, который в данном случае является Элементом. Вы также должны знать, что при вызове другой функции внутри функции eventListening ее контекст this не становится связанным с Элементом. Функции со стрелками, конечно, работают по-разному, поскольку их this поднимается до уровня области действия, где он остается, поэтому связывание с ними бессмысленно. Другими словами, вы не можете использовать this.value или this.style.color в функции стрелки, как вы можете использовать в обычной функции, которая является EventListener.

...