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

Jquery滚动进度条代码转换为React下Vanilla JS时Math.round返回NaN问题

问题排查与修复方案

错误原因定位

NaN问题是核心变量取值错误导致除法运算出现非数值结果:

  • window.onscroll是滚动事件绑定属性,不是当前页面滚动距离,正确取值为window.scrollY(兼容所有现代浏览器)
  • document不存在offsetHeight属性,整个文档的总高度应取document.documentElement.scrollHeight
  • window不存在offsetHeight属性,浏览器视口高度应取window.innerHeight

同时存在两处和原jQuery逻辑不匹配的问题:

  • 原代码是给.fill设置高度,改写代码错误改为设置innerHTML
  • 原代码h1使用textColor、.fill背景使用bgColor,改写代码把颜色赋值逻辑搞反

修复后的原生JS版本(仅对齐原jQuery逻辑)

const progress = () => {
    const windowScrollTop = window.scrollY;
    const docHeight = document.documentElement.scrollHeight;
    const windowHeight = window.innerHeight;
    // 处理文档高度小于视口高度时,分母为负/0的边界情况
    const scrollableHeight = docHeight - windowHeight;
    const progressPercent = scrollableHeight <= 0 ? 100 : (windowScrollTop / scrollableHeight) * 100;
    
    const bgColor = progressPercent > 99 ? "#fff" : "#fff";
    const textColor = progressPercent > 99 ? "#fff" : "#333";
          
    document.querySelector("h1").innerHTML = Math.round(progressPercent) + "%";
    document.querySelector("h1").style.color = textColor;
    document.querySelector(".fill").style.height = progressPercent + "%";
    document.querySelector(".fill").style.backgroundColor = bgColor;
}
// 绑定滚动事件,否则仅页面加载时执行一次
window.addEventListener('scroll', progress);
progress();

React项目推荐写法(避免直接操作DOM)

React生态下更推荐用状态管理进度值,不要直接查询操作DOM:

import { useState, useEffect } from 'react';

const ProgressBar = () => {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const handleScroll = () => {
      const windowScrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight;
      const windowHeight = window.innerHeight;
      const scrollableHeight = docHeight - windowHeight;
      const currentProgress = scrollableHeight <= 0 ? 100 : (windowScrollTop / scrollableHeight) * 100;
      setProgress(Math.round(currentProgress));
    };

    window.addEventListener('scroll', handleScroll);
    handleScroll(); // 初始化进度
    return () => window.removeEventListener('scroll', handleScroll); // 组件卸载时清除事件
  }, []);

  const textColor = progress > 99 ? "#fff" : "#333";
  const fillBgColor = progress > 99 ? "#fff" : "#fff";

  return (
    <div className="progress-container">
      <h1 style={{ color: textColor }}>{progress}%</h1>
      <div className="fill" style={{ height: `${progress}%`, backgroundColor: fillBgColor }} />
    </div>
  );
};

export default ProgressBar;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:45:03