javascript - 如何延迟路口观察者 API

标签 javascript settimeout intersection-observer

情况

我在页面顶部有一个固定的导航栏。当您向下滚动页面的不同部分时,导航栏会动态更新(下划线和突出显示)。您还可以单击导航栏上的某个部分,它会向下滚动到该部分。

这是通过使用 intersection observer API 来检测它位于哪个部分并使用 scrollIntoView 滚动到每个部分来完成的。

问题

假设您在第 1 部分,然后单击最后一个部分 5,它会将页面向下滚动到中间的所有其他部分。滚动速度很快,当它滚动时,路口观察器会检测到所有部分,因此导航会更新。当每个导航项目经过每个对应部分时,您最终会得到导航快速变化的效果。

目标

如果该部分仅在帧中一毫秒,您如何延迟交叉点观察器触发菜单更改?快速滚动时,导航栏应仅在滚动停止在某个部分上后更新。

代码设置

const sectionItemOptions = {
  threshold: 0.7,
};

const sectionItemObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {

    if (entry.isIntersecting) {
      // select navigation link corresponding to section

    } else {
      // deselect navigation link corresponding to section

    }
  });
}, sectionItemOptions);

// start observing all sections on page
sections.forEach((section) => {
  sectionItemObserver.observe(section);
});

想法

我的第一个想法是设置一个 setTimeout,这样在超时完成之前导航不会改变,然后如果该部分在超时完成之前离开屏幕,则取消超时。但是由于超时在 forEach 循环中,所以这不起作用。

const sectionItemObserver = new IntersectionObserver((entries, observer) => {
  entries.forEach((entry) => {

    let selectNavTimeout

    if (entry.isIntersecting) {

      // Set timeout when section is scrolled past
      selectNavTimeout = setTimeout(() => {
        // select navigation link corresponding to section
      }, 1000)

    } else {
      // deselect navigation link corresponding to section
      // cancel timeout when section has left screen
      clearTimeout(selectNavTimeout)
    }
  });
}, sectionItemOptions);

任何其他想法将不胜感激!谢谢:)

最佳答案

我遇到了同样的问题。我最终使用 setTimeout 方法。您需要将超时与入口目标相关联,前提是每个入口目标都有一些唯一的 ID。例如,假设我们正在与具有 id 属性的节点相交:

    let timeouts = {};
    const observer = new IntersectionObserver((entries, ob) => {
        for (const e of entries) {
            if (e.isIntersecting) {
                timeouts[e.target.id] = setTimeout(() => {
                    ob.unobserve(e.target)

                    // handling

                }, 1000)  // delay for 1 second
            } else {
                clearTimeout(timeouts[e.target.id])
            }
        }
    }, options)

关于javascript - 如何延迟路口观察者 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61802983/

相关文章:

jquery - setTimeout 不适用于 jquery.each,这

javascript - 相对于视口(viewport),Intersection Observer 是否从跨域 iframe 内部工作?

javascript - ExtJs 4 - 如何拖放文本(或文本区域)字段的内容?

javascript - 如何在 Excel VBA 中使用 Selenium Webdriver 滚动下拉菜单

JavaScript setTimeout 运行两次

javascript - javascript中的setTimeout使函数运行得更快

javascript - 如何将我的表单链接到一个函数?

javascript - 我可以在 Angular JS 中的对象数组中只观察一个变量的变化吗?

typescript - 在 Jest 和 typescript 中模拟交叉点观察者

javascript - 我如何使用 Intersection Observers 来判断何时有东西占据了整个视口(viewport)?