我试图显示一个特定的组件 - 当显示它的页面从顶部滚动 X 个点时,它是一个“粘性标题”部分。
我尝试使用 useWindowScroll
执行此操作钩子(Hook) use-react
包,以及下面的一个简短片段:
const [scrollTop, setScrollTop] = useState(0);
function setScroll() {
console.log('setScroll');
setScrollTop(window.pageYOffset);
console.log(new Date().getTime());
}
useEffect(() => {
function watchScroll() {
console.log('watchScroll');
window.addEventListener("scroll", setScroll);
}
watchScroll();
return () => {
window.removeEventListener("scroll", setScroll);
};
});
console.log('scroll top:', scrollTop);
理想情况下,我们可能希望在处理每个新的滚动事件之前有一点延迟,但这不是我的问题。
我希望setScroll
每当我滚动时,每隔几毫秒就会被调用。然而,这并没有发生。事实上,我从未见过它被调用过。
由于它没有在适当的时候被调用,我的const shouldShowStickyHeader = scrollTop > 1000;
始终设置为 false
。因此,我的从未显示过。我希望它在滚动到顶部距离为 1,000 时出现。
问题是什么?
我还尝试了效果 Hook 内所有内容的版本:
const [scrollTop, setScrollTop] = useState(0);
useEffect(() => {
function setScroll() {
console.log('setScroll');
setScrollTop(window.pageYOffset);
console.log(new Date().getTime());
}
window.addEventListener("scroll", setScroll);
return () => {
window.removeEventListener("scroll", setScroll);
};
}, [scrollTop]);
我没看到setScroll
正在控制台中打印。可能是什么问题?
我用 document.querySelectorAll("*").forEach(element => element.addEventListener("scroll", ({target}) => console.log(target, target?.id, target?.parent, target?.parent?.id)));
做了一个小测试。当我滚动时确实会触发一些事件。请参阅:
<div data-testid="vdp-scroll-container" id="vdp-scroll-container" class="jsx-1959376998 vdp-scroll-container">
...
<div data-testid="vdp-scroll-container" id="vdp-scroll-container" class="jsx-1959376998 vdp-scroll-container">
我尝试将列表直接放在这个元素上:
document.getElementById('#vdp-scroll-container')?.addEventListener("scroll", setScroll);
return () => {
document.getElementById('#vdp-scroll-container')?.removeEventListener("scroll", setScroll);
};
不过,我没有看到任何东西被解雇。
此 <div/>
上的样式如下:
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow-y: scroll;
因此我什么也得不到吗?
最佳答案
您应该将一个空数组传递给 useEffect 作为第二个参数,以便仅在组件第一次安装后才触发该函数。不传递第二个参数,将在每次重新渲染后触发该函数,传递 [scrollTop]
将在每次 scrollTop
更改时触发该函数。
这样的事情应该有效:
const [offset, setOffset] = React.useState(null);
const setScroll = () => {
setOffset(window.scrollY);
};
React.useEffect(() => {
window.addEventListener("scroll", setScroll);
return () => {
window.removeEventListener("scroll", setScroll);
};
}, []);
工作示例:https://codesandbox.io/s/zen-cdn-ll6es?file=/src/App.js
关于javascript - React 应用程序没有按预期触发 onScroll 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68944015/