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

Next.js中如何监听document滚动高度变化,解决document未定义报错

问题原因

Next.js 默认开启服务端渲染/静态生成能力,服务端运行代码时不存在document、window等浏览器全局对象,你原代码直接把document.documentElement.scrollHeight放在 useEffect 依赖数组中,服务端初始化执行依赖解析时就会直接抛出未定义错误。

最优实现方案

用ResizeObserver监听文档根元素的尺寸变化来感知滚动高度变更,性能远优于定时轮询方案,同时做好浏览器环境判断避免服务端执行报错。

完整代码实现
import { useEffect, useRef, useState } from 'react'

// 组件内部逻辑
const [docScrollHeight, setDocScrollHeight] = useState(0)
const resizeObserverRef = useRef(null)

// 监听文档滚动高度变化
useEffect(() => {
  // 服务端环境直接跳过
  if (typeof window === 'undefined') return

  resizeObserverRef.current = new ResizeObserver((entries) => {
    for (const entry of entries) {
      setDocScrollHeight(entry.target.scrollHeight)
    }
  })
  // 监听根元素尺寸变化,也可以替换为你实际内容容器的DOM节点,监听更精准
  resizeObserverRef.current.observe(document.documentElement)

  // 组件卸载清理观察者,避免内存泄漏
  return () => {
    resizeObserverRef.current?.disconnect()
  }
}, [])

// 执行自动滚动逻辑
useEffect(() => {
  if (typeof window === 'undefined') return
  if (postdata.isLoading || postProgress == null) return

  const heightWin = docScrollHeight - document.documentElement.clientHeight
  const offset = postProgress / 100
  const offsetScroll = offset * heightWin
  window.scrollTo(0, offsetScroll)
}, [postinfo.isLoading, postdata.isLoading, postProgress, docScrollHeight])
说明
  • 所有浏览器API调用都添加了环境判断守卫,完全规避服务端执行报错问题
  • 依赖数组不再直接引用document相关属性,避免服务端解析依赖阶段触发错误
  • ResizeObserver会在元素尺寸变更时自动触发回调,无多余性能开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 23:06:03