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

Next+TypeScript项目如何检测元素进出视口修改导航栏样式

实现方案(推荐:无需jQuery,完美适配Next.js + TypeScript)

报错原因说明

你遇到的window is undefined报错是因为Next.js默认开启服务端预渲染,服务端运行环境不存在window、document等浏览器专属API,直接引入jQuery或者在组件顶层操作浏览器API都会触发该错误。使用React原生Hook实现不需要引入额外依赖,也能完全规避TS兼容问题。

完整实现代码

import { NextPage } from 'next';
import { useState, useEffect, useRef } from 'react';
// 引入样式文件,也可以用CSS-in-JS方案
import styles from './Home.module.css';

const Home: NextPage = () => {
  // 存储导航是否滚动到目标位置的状态
  const [isNavActive, setIsNavActive] = useState(false);
  // 绑定目标div的ref,用于获取位置信息
  const targetDivRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // 仅在客户端环境执行
    if (typeof window === 'undefined') return;

    const handleScroll = () => {
      if (!targetDivRef.current) return;
      // 获取目标div距离页面顶部的高度
      const targetTop = targetDivRef.current.offsetTop;
      // 获取当前页面滚动距离
      const scrollTop = window.scrollY;
      // 滚动位置超过目标div顶部时修改状态
      setIsNavActive(scrollTop >= targetTop);
    };

    // 绑定滚动监听事件
    window.addEventListener('scroll', handleScroll);
    // 组件卸载时解绑事件,避免内存泄漏
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return (
    <>
      {/* 动态绑定样式类 */}
      <nav className={`${styles.nav} ${isNavActive ? styles.navActive : ''}`}>
        <ul>
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
        </ul>
      </nav>
      <main>
        <div id="firstDiv">
         {/* more code */}
        </div>
        {/* 给目标div绑定ref */}
        <div id="divToHideNav" ref={targetDivRef}>
         {/* more code */}
        </div>
      </main>
    </>
  );
};

export default Home;

样式示例(Home.module.css)

.nav {
  position: fixed;
  top: 0;
  width: 100%;
  padding: 20px;
  background: transparent;
  transition: all 0.3s ease;
  z-index: 999;
}

.navActive {
  background: #fff;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  color: #000;
}

可选:jQuery兼容实现方案

如果必须使用jQuery,需要确保仅在客户端动态引入,避免服务端预渲染阶段执行:

useEffect(() => {
  if (typeof window === 'undefined') return;
  // 动态引入jQuery
  import('jquery').then($ => {
    const handleScroll = () => {
      const targetTop = $('#divToHideNav').offset()?.top || 0;
      if ($(window).scrollTop() >= targetTop) {
        $('#myNav').addClass('active');
      } else {
        $('#myNav').removeClass('active');
      }
    };
    $(window).on('scroll', handleScroll);
    return () => $(window).off('scroll', handleScroll);
  });
}, []);

注意:该方案需要先安装jQuery和对应的TS类型依赖:npm i jquery @types/jquery

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:15:05