Next.js App目录下scroll事件未触发,如何获取当前scrollY值?
解决Next.js App目录中window.scroll事件不触发的问题
问题原因
Next.js App Router的根布局默认会调整页面的滚动容器逻辑,不再以传统的window/body作为滚动载体,而是将滚动行为委托给了内部容器(比如main元素或Next.js自定义容器),导致监听window的scroll事件无法捕获到页面滚动动作。
解决方案
1. 定位实际滚动容器
先在浏览器控制台执行以下代码,确认当前页面的滚动元素:
console.log(document.scrollingElement);
App Router环境下,这个元素通常是html、body,或是根布局中的某个自定义容器。
2. 监听正确的滚动元素
根据定位到的滚动元素,修改事件监听目标:
'use client'; import { useEffect } from 'react'; const Page = () => { const handleScroll = () => { // 用document.scrollingElement获取滚动位置,兼容不同场景 console.log(document.scrollingElement.scrollTop); }; useEffect(() => { const scrollElement = document.scrollingElement; if (scrollElement) { scrollElement.addEventListener('scroll', handleScroll); return () => scrollElement.removeEventListener('scroll', handleScroll); } }, []); // 空依赖数组确保仅在组件挂载时绑定一次事件 return ( <div style={{ minHeight: '200vh' }}> 滚动页面测试scroll事件 </div> ); }; export default Page;
3. 备选方案:强制让window成为滚动容器
如果需要固定使用window作为滚动容器,可以在根layout.js中修改样式,禁用内部容器的滚动:
// app/layout.js export default function RootLayout({ children }) { return ( <html lang="en" style={{ height: '100%', overflow: 'auto' }}> <body style={{ height: '100%', margin: 0, overflow: 'visible' }}> {children} </body> </html> ); }
修改后再监听window的scroll事件即可正常触发。
内容的提问来源于stack exchange,提问作者Azura
相关产品推荐
相关产品推荐

