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

原生JavaScript页面滚动进度条实现问题求助

Fixing Your Vanilla JS Scroll Progress Bar Issues

Hey there! Let’s walk through each of your problems and get that scroll progress bar working as expected.

1. Why document.body.scrollTop always returns 0

You already nailed the fix with document.scrollingElement.scrollTop—great call! Here’s the breakdown:

  • Browsers have inconsistent default scroll elements: Chrome and Edge use the <html> element, while older Firefox versions relied on <body>.
  • document.scrollingElement is the standard, cross-browser way to grab the root element that handles page scrolling. Stick with this for all scroll-related calculations.

2. Fixing the progress calculation offset issue

Your core logic is almost right, but the problem comes from mismatched elements in your height calculation. You’re using document.body.scrollHeight but should pair it with the same scrolling element you use for scrollTop. Here’s the corrected code:

const progressBar = document.getElementById('footer__progress_bar');
let totalValue;

// Calculate total scrollable height (and update on resize)
const updateTotalValue = () => {
  totalValue = document.scrollingElement.scrollHeight - window.innerHeight;
};

// Initialize on page load
updateTotalValue();
// Update when window size changes
window.addEventListener('resize', updateTotalValue);

document.body.onscroll = () => {
  const currentValue = document.scrollingElement.scrollTop;
  // Avoid division by zero if page is shorter than viewport
  if (totalValue <= 0) {
    progressBar.style.left = '0%';
    return;
  }
  // Your original logic works once totalValue is accurate
  const offset = (currentValue / totalValue) * 100 - 100 + '%';
  progressBar.style.left = offset;
};

Key improvements here:

  • Use document.scrollingElement.scrollHeight instead of document.body.scrollHeight for consistent, accurate total height.
  • Add a resize listener to update totalValue when the window resizes (this fixes offset glitches from viewport changes).
  • Add a guard clause to prevent division by zero if the page content is shorter than the viewport.

3. Why page height values (clientHeight/offsetHeight) are inconsistent

The random fluctuations you’re seeing are likely caused by:

  • Unloaded assets: Images, fonts, or dynamic content loading after your initial height check, which shifts the page’s total height.
  • Browser scrollbar space: window.innerHeight excludes the scrollbar (if present), which can change depending on whether content overflows.
  • CSS box model differences: clientHeight ignores borders and scrollbars, while offsetHeight includes them. If your <body> has padding or borders, these values will naturally differ.

To fix this:

  • Stick with document.scrollingElement.scrollHeight for the full page height—it accounts for all content, including dynamically loaded elements.
  • Wait for all assets to load before calculating heights (use window.onload instead of DOMContentLoaded if you have images, or listen for load events on specific assets).

4. Why main.scrollTop returns 0

scrollTop only has a non-zero value when an element has a scrollbar—meaning its content overflows its defined height, and overflow is set to auto or scroll. Since you’ve set main to height: auto, it expands to fit its content, so there’s no overflow to scroll through.

If you wanted <main> to scroll independently of the page, you’d need to:

  • Set a fixed height on <main> (e.g., height: 100vh;)
  • Add overflow-y: auto; to it
  • Listen for scroll events on <main> instead of the document.

But since your goal is a page-wide scroll progress bar, sticking with document.scrollingElement is the right call.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:31:58