首页 > 解决方案 > 根据当前部分更改滚动元素背景并优化性能

问题描述

.wrapper这个想法是根据当前部分更改背景。不幸的是,有一些限制。我需要根据当前window.scrollTop不是当前在视口中的哪个部分section.offsetTop来更改它。(IntersectionObserver将不起作用)

它将类似于 scrollSpy,但由于性能原因,我无法遍历每个滚动事件中的所有部分。此外,我正在使用虚拟滚动插件进行平滑滚动,这使得滚动的计算量更大。

对于我到目前为止的代码:

我的部分如下所示:

<section class="intro"
  data-bg="#ffffff"
  data-color="#1A1919"
>
  Section content goes here
</section>

我有一个对象数组。在每个对象中,我都有节点元素及其顶部。

const sections = [
  {
    el: section.intro, // Node
    top: 1224 // Number
  },
  ....
]

我可以从滚动插件中获取 scrollTop。所以现在的代码看起来像:

const wrapper = document.querySelector('.wrapper');

const changeBg = (scrollTop, sections) => {
  sections.map(({ el, top }) => {
    const bg = el.getAttribute('data-bg');
    const color = el.getAttribute('data-color');

    if (top < scrollTop + window.innerHeight) {
      console.log(bg);
      wrapper.style.backgroundColor = bg;
      wrapper.style.color = color;
    }
  });
};

myCustomPluginForScroll.on('scroll', e => {
  const { y } = e.scroll;

  changeBg(y, sections);
});

问题是:

  1. 我在每个滚动事件上循环所有部分(从插件中乘以许多以进行平滑滚动),它会导致滚动滞后;
  2. 当我向下滚动更多时,越来越多的部分对于top < y + window.innerHeight每次滚动更改包装器背景更多次的条件变得有效。

changeBg由于平滑滚动插件,我无法使用 debouncer 进行较低的调用次数。

对于这个问题:

如何changeBg在从条件中添加/删除新部分时只调用一次,top < y + window.innerHeight并且仅在最后添加/删除的部分上获取 bg/color 属性。

附上带有 6 个部分的日志的屏幕截图bg并滚动到网站底部。这样,在每一个卷轴上,我都会更改 6 次包装器的背景。

来自 bg 的最后一个 console.log 的屏幕截图

标签: javascript

解决方案


推荐阅读