#javascript #simplemodal
#javascript #simplemodal
Вопрос:
Я смог закрыть свой модальный файл при нажатии на значок x и при нажатии кнопки escape. Как я могу также закрыть его при нажатии за пределами модального (т. Е. тела страницы?) Спасибо
document.querySelectorAll(".modal-trigger").forEach((trigger) => {
const modal = document.querySelector(trigger.dataset.modal);
const closeBtn = modal.querySelector(".modal-close");
function open() {
modal.classList.add("show-modal");
trigger.blur();
document.body.style.overflow = "hidden";
document.body.addEventListener("keydown", escapeClose);
}
function close() {
modal.classList.remove("show-modal");
document.body.style.overflow = "auto";
document.body.removeEventListener("keydown", escapeClose);
}
function escapeClose(event) {
if (event.keyCode === 27) {
close();
}
}
trigger.addEventListener("click", open);
closeBtn.addEventListener("click", close);
});
Ответ №1:
Вот что я в итоге сделал. Спасибо!
document.querySelectorAll(".modal-trigger").forEach((trigger) => {
const modal = document.querySelector(trigger.dataset.modal);
const closeBtn = modal.querySelector(".modal-close");
function open(event) {
modal.classList.add("show-modal");
trigger.blur();
document.body.style.overflow = "hidden";
document.body.addEventListener("keydown", escapeClose);
modal.addEventListener("click", outsideClose);
event.stopPropagation();
}
function close() {
modal.classList.remove("show-modal");
document.body.style.overflow = "auto";
document.body.removeEventListener("keydown", escapeClose);
modal.removeEventListener("click", outsideClose);
}
function escapeClose(event) {
if (event.keyCode === 27) {
close();
}
}
function outsideClose(event) {
if (
event.target === modal ||
event.target.classList.contains("close-modal")
) {
close();
}
}
trigger.addEventListener("click", open);
closeBtn.addEventListener("click", close);
});
Комментарии:
1. Разве это не закрывает модальный, если пользователь нажимает внутри модального элемента? Не должно ли это быть
event.target != modal
вместо этого?2. Это действительно было проблемой для меня, мне потребовалось некоторое время, чтобы разобраться, поэтому в модальной переменной у меня есть div, который служит фоном. Итак, если модал получает щелчок, и если целью является он сам, это означает, что я щелкнул не в модальном контенте, а вместо этого в фоновом режиме, поэтому я закрываю модал. Итак, если я это сделаю
event.target != modal
, это приведет к обратному результату: закрывается, когда я нажимаю на модальный, а не когда я нажимаю на фон, это работает, но, вероятно, есть более простой способ сделать это.3. Я опубликую свое очень простое и универсальное решение, в котором используется логический (! not) оператор, чтобы проверить, находится ли щелчок внутри или за пределами модала.
Ответ №2:
Вы могли бы сделать следующее
document.addEventListener('click', function(e) {
if (e.target.closest(trigger.dataset.modal) == null) {
close();
}
})
Это вызовет метод closest() для любого элемента, на который был нажат. Closest() перемещается ВВЕРХ по dom с того места, где он начинается. Итак, если вы нажмете за пределами модального файла, это вернет нулевое значение. Если вы щелкните элемент внутри модального файла, он вернет сам модальный файл. Вы должны быть в состоянии предположить, что если возвращаемое значение равно null, то щелчок был произведен за пределами модального файла.
Дополнительная информация о closest()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Ответ №3:
Попробуйте изменить стиль непосредственно с помощью прослушивателя событий.
window.onclick = (e) => {
if (e.target == modal) {
modal.style.display = "none";
}
}
Ответ №4:
Мне нравится это решение, которое я, вероятно, нашел здесь, в Stackoverflow:
// Close modal on outside click
const modal = document.querySelector('.modal')
document.addEventListener('click', (e) => {
let clickInside = modal.contains(e.target)
if (!clickInside) {
modal.classList.remove('show')
}
})