функция сама вызывается - при навешивании слушателя внутри другой функции
Пример здесь на codepen.io
Добавляю слушатель внутри функции document.addEventListener('click', closePopup), а он сразу исполняется с текущим event. :(
Помогите понять, почему? и как это исправить?
const button = document.querySelector('.button');
const popup = document.querySelector('.popup');
function closePopup(event) {
console.log(event.target)
if (!event.target.closest('.popup')) {
removeClassActivePopup()
}
}
function removeClassActivePopup() {
button.classList.remove('button_active')
popup.classList.remove('popup_visible')
document.removeEventListener('click', closePopup)
}
function addClassActivePopup() {
// если закомитить навешивание слушателя - работает
// функция closePoupup вызывается при навешивании с текущим event и закрывает popup
document.addEventListener('click', closePopup)
button.classList.add('button_active')
popup.classList.add('popup_visible')
}
function showPopupSetting(e) {
if (button.matches('.button_active')) {
removeClassActivePopup()
} else {
addClassActivePopup()
}
}
button.addEventListener('click', showPopupSetting)
Ответы (2 шт):
Вы добавляете обработчик события документу до того, как это событие "всплывет" до документа.
function clickDocument() {
console.log('clickDocument');
}
function clickButton() {
console.log('clickButton');
document.addEventListener("click", clickDocument);
}
document.getElementById("test").addEventListener("click", clickButton);
<button id="test">Click</button>
function clickDocument() {
console.log('clickDocument');
}
function clickButton(e) {
e.stopPropagation();
console.log('clickButton');
document.addEventListener("click", clickDocument);
}
document.getElementById("test").addEventListener("click", clickButton);
<button id="test">Click</button>
На самом деле проблема в 3 параметре addEventListener
useCapture
Если равно true, useCapture указывает, что пользователь желает начать захват. После инициализации захвата все события указанного типа будут отправлены в зарегистрированный listener перед отправкой в какой-либо EventTarget под ним в дереве DOM. События, восходящие вверх по дереву, не будут вызывать слушателей, которым назначено использовать захват. Смотрите DOM Level 3 Events для более детального объяснения. Значение useCapture по умолчанию равно false.
function clickDocument() {
console.log('clickDocument');
}
function clickButton() {
document.addEventListener("click", clickDocument, true);
console.log('clickButton');
}
document.getElementById("test").addEventListener("click", clickButton);
<button id="test">Click</button>
против
function clickDocument() {
console.log('clickDocument');
}
function clickButton() {
document.addEventListener("click", clickDocument);
console.log('clickButton');
}
document.getElementById("test").addEventListener("click", clickButton);
<button id="test">Click</button>
Обратите внимание на первый клик, до того как навешан был обработчик.