我正在练习一个视频课程中有关模态窗口的课程,并注意到一个功能:当我滚动到页面末尾时,我运行了一个“onscroll”事件,并且在关闭模态窗口后,该事件拒绝进一步触发,因此一开始我不明白为什么作者要为这个事件的单个触发编写逻辑。
这就是为什么我对弄清楚这一点变得很有趣。正如我注意到的,页面高度恰好是 4264px。当第一次触发该事件时,条件“window.Scrollly + document.documentElement.clientHeight”给我们4264px,但是当再次触发时,该值已经等于4263.8,这不足以满足条件。据我了解,这是由于 body 元素的溢出变化造成的。
我决定解决这个问题并开始向上舍入这个值,但我遇到了另一个问题:现在,当我滚动到底部时重新打开模式窗口时,根本无法关闭它。 当您单击十字关闭它时,控制台中会显示两次铭文,表明滚动事件被触发并且条件也满足,尽管此时溢出=隐藏,我无法在任何情况下触发此事件不再这样了。 但是,如果我在弹出模式窗口中的标记内写入任何字符,那么我可以安全地关闭模式窗口,并且它不再从此事件中弹出,直到我再次向下滚动页面。 我还注意到“设置计时器”类型的解决方案不起作用,并且该事件再次触发两次。 为什么会发生这种情况? 代码部分:
完整项目(问题从 script.js 中的第 97 行开始):https://github.com/sevabek/tt/tree/main/%D1%80%D0%B5%D0%B0%D0%BB% D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%20%D1%82%D0%B0%D0%B1%D0%BE%D0%B2
**尝试使用此代码**
const modalTrigger = document.querySelectorAll("[data-modal]"),
modal = document.querySelector(".modal"),
modalCloseBtn = document.querySelector("[data-close]");
let modalIsOpen = false;
let modalTimerId;
let scrollDebounceTimer;
function openModal() {
if (!modalIsOpen) {
modal.classList.add("show");
modal.classList.remove("hide");
document.body.style.overflow = "hidden";
clearInterval(modalTimerId);
modalIsOpen = true;
}
}
modalTrigger.forEach((item) => {
item.addEventListener("click", () => {
openModal();
});
});
function closeModal() {
if (modalIsOpen) {
modal.classList.add("hide");
modal.classList.remove("show");
document.body.style.overflow = "scroll";
modalIsOpen = false;
// Introduce a small delay before checking the scroll position again
clearTimeout(scrollDebounceTimer);
scrollDebounceTimer = setTimeout(() => {
if (
Math.ceil(window.scrollY + document.documentElement.clientHeight) >=
document.documentElement.scrollHeight
) {
console.log("scrolled down");
openModal();
}
}, 100);
}
}
modalCloseBtn.addEventListener("click", () => {
closeModal();
});
modal.addEventListener("click", (e) => {
if (e.target === modal) {
closeModal();
}
});
document.addEventListener("keydown", (e) => {
if (e.code === "Escape" && modal.classList.contains("show")) {
closeModal();
}
});
modalTimerId = setTimeout(openModal, 15_000);
window.addEventListener("scroll", () => {
// Debounce the scroll event
clearTimeout(scrollDebounceTimer);
scrollDebounceTimer = setTimeout(() => {
if (
Math.ceil(window.scrollY + document.documentElement.clientHeight) >=
document.documentElement.scrollHeight
) {
console.log("scrolled down");
openModal();
}
}, 100);
});