You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js的_document.js中实现条件式overflow样式

解决方案:根据页面动态设置html/body的overflow样式

问题原因

useRouter 无法在 MyDocument 类组件中使用——它是客户端React钩子,而Document是服务端渲染的根组件,仅在服务端和页面初始加载阶段运行,无法访问客户端路由钩子。

方案1:通过Document的getInitialProps传递路径(服务端判断)

修改MyDocument的getInitialProps方法,从上下文获取当前页面路径,再在render阶段根据路径动态设置样式:

import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { CssBaseline } from '@nextui-org/react';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    // 从上下文提取当前页面路径
    const { pathname } = ctx;
    return {
      ...initialProps,
      styles: React.Children.toArray([initialProps.styles]),
      pathname // 将路径传递给组件props
    };
  }

  render() {
    const { pathname } = this.props;
    // 判断当前页面
    const isAboutPage = pathname === '/about';
    const isContactPage = pathname === '/contact';

    return (
      <Html 
        lang="en" 
        style={{ 
          overflow: isAboutPage ? 'hidden' : 'auto' // About页面隐藏html滚动,其他页面默认auto
        }}
      >
        <Head>{CssBaseline.flush()}</Head>
        <body 
          style={{ 
            overflow: isContactPage ? 'hidden' : 'auto' // Contact页面隐藏body滚动,其他页面默认auto
          }}
        >
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

方案2:页面内直接操作DOM(快速取巧)

如果不想修改根文档组件,可直接在目标页面的客户端组件中操作DOM,适合快速修复:

About页面示例

import { useEffect } from 'react';

export default function About() {
  useEffect(() => {
    // 设置当前页面样式
    document.documentElement.style.overflow = 'hidden';
    document.body.style.overflow = 'auto';

    // 页面卸载时恢复默认样式,避免影响其他页面
    return () => {
      document.documentElement.style.overflow = 'auto';
      document.body.style.overflow = 'auto';
    };
  }, []);

  return <div>About Page Content</div>;
}

Contact页面示例

import { useEffect } from 'react';

export default function Contact() {
  useEffect(() => {
    // 设置当前页面样式
    document.documentElement.style.overflow = 'auto';
    document.body.style.overflow = 'hidden';

    // 页面卸载时恢复默认样式
    return () => {
      document.documentElement.style.overflow = 'auto';
      document.body.style.overflow = 'auto';
    };
  }, []);

  return <div>Contact Page Content</div>;
}

注意事项

  • 方案1是服务端渲染时直接注入样式,适合全局统一控制;
  • 方案2更轻量化,无需修改根文档组件,适合快速解决单页面的样式需求;
  • 必须在组件卸载时恢复默认样式,避免影响其他页面的滚动行为。

内容的提问来源于stack exchange,提问作者The_FORUM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:41:25