use*_*307 4 ref overlap reactjs
我正在查看许多检查元素是否重叠的答案,但它们不适用。
我有一个包装组件,它有一个位置固定的标头和子组件
const Wrapper = ({ children }) => {
return (
<>
<Header/>
{children}
</>
)
};
export default Wrapper
Run Code Online (Sandbox Code Playgroud)
我需要知道标题何时与几个不同页面(子页面)中的某些部分重叠,以便更改标题颜色
我试图在包装器组件中进行检测,但元素不存在或容器无法访问
我是否需要将引用从包装器一直传递给所有孩子?有没有更简单的方法来做到这一点?
谢谢
我能想到几种方法,一种是你提到的方法,传递参考文献并进行一系列计算,还有下面的一些方法。
这基本上可以通过在头文件中包含一个大的 switch case 并检查滚动目标的偏移滚动位置来实现。
getBackgroundColor = (scrollPosition) => {
switch (true) {
case scrollPosition <= $('#page1').height:
return 'red'
case scrollPosition <= $('#page1').height + $('#page2').height:
return 'blue'
case scrollPosition <= $('#page1').height + $('#page2').height + $('page3').height
return 'green'
default:
return 'yellow'
}
}
Run Code Online (Sandbox Code Playgroud)
这有明显的缺陷,一是,如果页面内容是动态的或者经常变化,它可能不起作用,每次重新渲染时检查高度可能会导致回流问题,而这需要了解页面上的页面ID。(注意:这个片段只是为了证明概念,它需要几周的时间)。
Intersection Observer是一个很棒的 API,它允许您以高性能的方式观察元素,并通过恒定测量减少替代方式的布局抖动,这是我用 React 和 Intersection Observer 制作的一个示例,https: //codesandbox.io/s/relaxed-斯宾塞-yrozp。如果您有数百个目标,这可能不是最好的,但我还没有对此进行任何基准测试,所以不确定。它也被认为是“实验性的”,但具有良好的浏览器支持(不是 IE)。
以下是下面的大部分代码和框,只是为了获得一个想法。
React.useEffect(() => {
let headerRect = document.getElementById("header").getBoundingClientRect();
let el = document.getElementById("wrapper");
let targets = [...document.getElementsByClassName("block")];
let callback = (entries, observer) => {
entries.forEach(entry => {
let doesOverlap = entry.boundingClientRect.y <= headerRect.bottom;
if (doesOverlap) {
let background = entry.target.style.background;
setColor(background);
}
});
};
let io = new IntersectionObserver(callback, {
root: el,
threshold: [0, 0.1, 0.95, 1]
});
targets.forEach(target => io.observe(target));
return () => {
targets.forEach(target => io.unobserve(target));
};
}, []);
Run Code Online (Sandbox Code Playgroud)
另请注意,这不是最“React”的做事方式,因为它很大程度上依赖于ids,但是您可以通过在我使用过 dom 选择的所有地方传递 ref 来解决这个问题,但这可能会变得笨拙。