首页 > 解决方案 > 让 Intersection Observer 更精确、更高效

问题描述

背景

我在我的 React 应用程序中使用 Intersection Observer 来跟踪我在滚动页面时所处的类别。我想观察离菜单栏最近的 div。

让它更精确

为了更好地可视化这一点,我录制了一个小屏幕录像。您可以看到它在“Signature”和“Baser”之间切换,不是随机的,但不是我希望它切换的方式。当 div 几乎与菜单栏对齐时,我希望它切换到菜单栏中的其他项目。

我的录屏:https ://www.youtube.com/watch?v=ZF8qbLAQhWQ

如何处理性能

由于我使用的是 React,所以当我滚动页面时想要更新活动菜单项时,我将更新一个状态。为此,我正在使用他们的新钩子 API。

//page height: 1140
//observerMargin: 570
const observerMargin = Math.floor(pageHeight / 2);
const observerConfig = {
    rootMargin: `-${
        pageHeight % 2 === 0 ? observerMargin - 1 : observerMargin
    }px 0px -${observerMargin}px 0px`
};

useEffect(() => {
    const handleIntersection = function(entries) {
        entries.forEach(entry => {
            if (entry.target.id !== activeMenuProdCatId && entry.isIntersecting) {
                setActiveMenuProdCatId(entry.target.id); // setting the state here
            }
        });
    };

    const observer = new IntersectionObserver(handleIntersection, observerConfig);
    observer.observe(refs[menuProductCategory.name].current);

    return () => observer.disconnect();
}, [activeMenuProdCatId, setActiveMenuProdCatId, observerMargin, refs, pageHeight]);

我创建了一个函数,为要观察的每个 div 创建一个 ref,它将由 length 的menuProductCategories长度确定:

const refs = activeMenu.menuProductCategories.reduce((acc, next) => {
    acc[next.name] = createRef();
    return acc;
}, {});

在我的 JSX 中,我给每个 div 一个 ref 和一个 id:

<div
    id={menuProductCategory.id}
    ref={refs[menuProductCategory.name]}
>
    ...
</div>

在我的 PC 上执行此操作时效果很好,但在移动设备上,当我快速滚动页面时它会滞后。

这些是我面临的问题,我希望得到一些指导。我也希望我的描述性足够,否则,请告诉我。

谢谢!

标签: javascriptreactjsintersection-observer

解决方案


推荐阅读