滚动页面时会触发两次onscroll事件

问题描述 投票:0回答:1

我正在练习一个视频课程中有关模态窗口的课程,并注意到一个功能:当我滚动到页面末尾时,我运行了一个“onscroll”事件,并且在关闭模态窗口后,该事件拒绝进一步触发,因此一开始我不明白为什么作者要为这个事件的单个触发编写逻辑。

这就是为什么我对弄清楚这一点变得很有趣。正如我注意到的,页面高度恰好是 4264px。当第一次触发该事件时,条件“window.Scrollly + document.documentElement.clientHeight”给我们4264px,但是当再次触发时,该值已经等于4263.8,这不足以满足条件。据我了解,这是由于 body 元素的溢出变化造成的。

我决定解决这个问题并开始向上舍入这个值,但我遇到了另一个问题:现在,当我滚动到底部时重新打开模式窗口时,根本无法关闭它。 当您单击十字关闭它时,控制台中会显示两次铭文,表明滚动事件被触发并且条件也满足,尽管此时溢出=隐藏,我无法在任何情况下触发此事件不再这样了。 但是,如果我在弹出模式窗口中的标记内写入任何字符,那么我可以安全地关闭模式窗口,并且它不再从此事件中弹出,直到我再次向下滚动页面。 我还注意到“设置计时器”类型的解决方案不起作用,并且该事件再次触发两次。 为什么会发生这种情况? 代码部分:https://i.stack.imgur.com/3q2mK.png

完整项目(问题从 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

javascript html web events
1个回答
0
投票

**尝试使用此代码**

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

© www.soinside.com 2019 - 2024. All rights reserved.