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

Next.js 13滚动事件监听器未触发问题求助

滚动事件监听器未生效的原因排查(Next.js 13 + Tailwind CSS)

问题根源

你的代码存在两个核心问题导致滚动事件监听器未生效:

  1. 事件监听器注册位置错误
    你将window.addEventListener("scroll", handleShadow, true);写在了handleShadow函数内部,这意味着只有当handleShadow被调用时才会注册监听器,但初始渲染时这个函数从未被执行,所以监听器根本没被添加到window上。

  2. 移除监听器的参数不匹配
    虽然你返回了移除监听器的函数,但如果监听器未被正确注册,移除操作毫无意义;另外,添加监听器时使用了第三个参数true(捕获阶段),移除时却没带上该参数,即使后续监听器被注册,也可能无法正确移除。

修正后的代码

状态与事件监听部分

const [shadow, setShadow] = useState(false);

useEffect(() => {
  const handleShadow = () => {
    // 简化状态更新逻辑
    setShadow(window.scrollY >= 90);
  };

  // 在useEffect初始化时直接注册滚动事件
  window.addEventListener("scroll", handleShadow, true);

  // 移除监听器时保持参数与添加时完全一致
  return () => {
    window.removeEventListener("scroll", handleShadow, true);
  };
}, []);

导航栏组件部分

可以用模板字符串简化className的条件判断,减少重复代码:

<div className={`fixed left-0 top-0 w-full z-10 ease-in duration-300 bg-[#112240] ${shadow ? 'shadow-xl' : ''}`}>
  {/* 其他导航栏内容 */}
</div>

关键修正说明

  • 将事件监听器的注册逻辑移到handleShadow函数外部,确保组件挂载时就完成监听器注册
  • 简化状态更新语句,直接用滚动位置的判断结果赋值给状态
  • 移除监听器时严格匹配添加时的所有参数,避免内存泄漏
  • 优化className的写法,利用Tailwind的类名组合特性减少冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:15:33