iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
JavaScript

解決學了JavaScript不知道能做什麼:用DOM操作打造實用網頁效果 系列 第 8 篇

【第八課】視窗控制:頁面滾動進度條(window.scrollY 與百分比計算)

  • 分享至 

  • xImage
  •  

前言

在 Medium、新聞部落格或長篇文件網站中,我們常看到頁面最頂端有一條「隨著滾動顯示閱讀進度」的進度條。這個設計能讓讀者清晰掌握剩餘文章長度,提升閱讀體驗。

觀念與函式深度解析

1. window.scrollY 與滾動高度計算

  • 為什麼選用這些屬性?

    要計算閱讀進度,我們必須知道三件事:

    1. 使用者目前滾動到了哪裡(window.scrollY)
    2. 整份網頁的總高度(document.documentElement.scrollHeight)
    3. 瀏覽器螢幕畫面的高度(window.innerHeight)
  • 這個計算邏輯在幹嘛?

    可滾動的最大距離 = 網頁總高度 - 螢幕高度。

    閱讀百分比(%)的計算公式為:(目前滾動位置 / 可滾動的最大距離) * 100

  • 有沒有其他替代方案?

    • 方案 A:window.pageYOffset
      • 簡介:scrollY 的舊版名稱。
      • 比較:現代瀏覽器皆已全面支援 window.scrollY,語意更簡短。

2. 動態修改 CSS 寬度 (progressBar.style.width = percentage + '%')

  • 為什麼選用這個方式?

    滾動進度是個連續變化的「百分比數字」(例如 12.5%, 45.8%),無法用固定的 Class 來切換,因此在這裡直接用 JS 操作 DOM 元素的 style.width 是最佳解法!

  • 這個語法在幹嘛?

    將計算出來的數字加上 % 單位字串,直接設定到頂部進度條條狀 DOM 的 CSS 寬度屬性上。

完整實作程式碼

<!DOCTYPE html>
<html lang="zh-TW">
<head>
  <meta charset="UTF-8">
  <title>第八課 - 頁面滾動進度條</title>
  <style>
    body { font-family: sans-serif; margin: 0; padding: 0; background-color: #f9f9f9; }

    /* 固定在視窗最頂部的進度條容器 */
    .progress-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 6px;
      background-color: #e0e0e0;
      z-index: 9999; /* 確保進度條最優先顯示 */
    }

    /* 填充顏色的進度條 */
    .progress-bar {
      height: 100%;
      width: 0%; /* 初始寬度為 0% */
      background-color: #3498db;
      transition: width 0.1s ease-out; /* 讓寬度變化稍微平滑 */
    }

    /* 文章內容樣式 (故意做長一點以產生滾動條) */
    .content { padding: 40px; max-width: 800px; margin: 0 auto; line-height: 1.8; }
    .paragraph { height: 300px; background: white; margin-bottom: 20px; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }</style>
</head>
<body>

  <!-- 頂部滾動進度條 -->
  <div class="progress-container">
    <div id="progressBar" class="progress-bar"></div>
  </div>

  <div class="content">
    <h1>30 天 DOM 操作實戰文章目錄</h1>
    <p>往下捲動頁面,觀察最頂部的藍色進度條變化</p>

    <!-- 模擬長文章區塊 -->
    <div class="paragraph"><h3>第一區塊:基礎 UI 互動</h3><p>閱讀內容中...</p></div>
    <div class="paragraph"><h3>第二區塊:常見網頁組件</h3><p>閱讀內容中...</p></div>
    <div class="paragraph"><h3>第三區塊:瀏覽器 API 應用</h3><p>閱讀內容中...</p></div>
    <div class="paragraph"><h3>第四區塊:API 資料串接</h3><p>閱讀內容中...</p></div>
    <div class="paragraph"><h3>第五區塊:專案實戰與優化</h3><p>閱讀內容中...</p></div>
  </div>

  <script>
    // ----------------------------------------------------
    // JavaScript 邏輯 (視窗滾動事件監聽)
    // ----------------------------------------------------

    // 第一步:取得進度條 DOM 元素
    const progressBar = document.getElementById("progressBar");

    // 第二步:監聽整頁的滾動事件 ('scroll')
    window.addEventListener("scroll", function(){

      // 1. 使用者目前向下滾動的垂直距離
      const scrollTop = window.scrollY;

      // 2. 網頁檔案的總高度
      const docHeight = document.documentElement.scrollHeight;

      // 3. 瀏覽器視窗目前可見的高度
      const windowHeight = window.innerHeight;

      // 4. 計算頁面「可供滾動」的最大總距離
      const totalScrollableDistance = docHeight - windowHeight;

      // 5. 計算當前的閱讀進度百分比 (%)
      // 防呆:避免除以 0 的情況(若頁面沒有滾動條)
      let scrollPercent = 0;
      if (totalScrollableDistance > 0) {
        scrollPercent = (scrollTop / totalScrollableDistance) * 100;
      }

      // 第三步:動態修改進度條條狀 DOM 的 CSS width 屬性
      progressBar.style.width = scrollPercent + "%";

    });</script>
</body>
</html>

下集預告

當使用者把長文章滑到底部時,要怎麼讓他們「一鍵快速回到最頂端」?

【第九課】視窗控制:「回到頂部(Back to Top)」按鈕與平滑滾動(scrollTo),我們將學習如何掌控頁面滾動的位置與平滑滑動效果。


上一篇
【第七課】作品整合 1:個人風格的「待辦事項(To-Do)標籤牆」(DOM 動態新增與刪除)
下一篇
第九課:【視窗控制】「回到頂部(Back to Top)」按鈕與平滑滾動
系列文
解決學了JavaScript不知道能做什麼:用DOM操作打造實用網頁效果 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言