Next.js 实现回到顶部按钮无法正确获取滚动位置问题求助
问题解决方案
你的问题根源是滚动行为没有发生在浏览器窗口上,而是你自定义的容器元素内部:
你给Base组件的根div设置了h-screen(高度等于设备视口高度)和overflow-y: auto属性,相当于把整个页面的滚动区域限制在了这个div内部,window本身不存在滚动,所以读取window.scrollY、监听window的scroll事件都不会得到正确结果。
修复步骤
- 给滚动容器div绑定React ref,用来访问真实DOM节点
- 把scroll事件监听器绑定到这个容器DOM上,而非window
- 滚动位置读取容器的
scrollTop属性,而非window.scrollY - 回到顶部方法调用容器的
scrollTo方法,而非window的同名方法 - 给useEffect添加空依赖数组,避免重复绑定事件导致性能问题
修复后代码示例
import { useState, useEffect, useRef } from 'react'; const Base = () => { const [showButton, setShowButton] = useState(false); // 给滚动容器加ref const scrollContainerRef = useRef<HTMLDivElement>(null); const handleScroll = () => { // 读取容器的scrollTop if (scrollContainerRef.current?.scrollTop > 300) { setShowButton(true); } else { setShowButton(false); } }; useEffect(() => { const container = scrollContainerRef.current; if (!container) return; // 给容器绑定滚动事件 container.addEventListener('scroll', handleScroll, true); return () => container.removeEventListener('scroll', handleScroll, true); }, []); // 空依赖仅在组件挂载/卸载时执行一次 const scrollToTop = () => { // 调用容器的滚动方法 scrollContainerRef.current?.scrollTo(0, 0); }; return ( // 给div绑定ref <div ref={scrollContainerRef} className="antialiased text-gray-600 h-screen w-screen flex flex-col overflow-y-auto"> {/* 其余原有组件内容 */} {showButton && <button onClick={scrollToTop}>回到顶部</button>} </div> ); };
内容的提问来源于stack exchange,提问作者Nikola-Milovic
相关产品推荐
相关产品推荐

