如何延迟路口观察者API

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

情况

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

这通过使用相交观察器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);

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

javascript settimeout intersection-observer
1个回答
0
投票

[经过大量的集思广益,我想出了一个想法,该想法不能完全回答延迟Intersection Observer API的问题,但确实解决了导航栏闪烁的问题。

导航项的突出显示是通过在其上添加“ is-active”类,然后对其应用CSS来完成的。由于“ is-active”类仅在导航项目上显示一秒钟,因此您可以使用CSS关键帧来延迟CSS样式的应用。延迟完成时,导航项目上不存在“ is-active”类,并且样式没有更改。

保持原始JS与使用的CSS相同

.is-active {
  animation: navItemSelected;
  animation-duration: 0.3s;
  // delay longer than the time nav item is in frame
  animation-delay: 0.1s;
  // fill mode to hold animation at the end
  animation-fill-mode: forwards;
}

@keyframes navItemSelected {
  // default non-selected style of nav item
  from {
    font-style: normal;
    opacity: 0.5;
  }
  // highlighted style of nav item
  to {
    font-style: italic;
    opacity: 1;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.