利用 JavaScript 自動為當前頁面側邊欄連結加上 active 樣式

前言

在多頁面網站中,常見需求是讓側邊欄或導覽列中的連結能自動標示當前所在頁面,提升使用者導覽體驗。這段程式碼示範如何透過 JavaScript 取得當前網頁路徑,並比對側邊欄所有連結的 href,對應到正確連結時自動加上「active」CSS 類別。適合需要動態控制導覽狀態的前端工程師或自學者。

取得並標準化當前頁面路徑

首先,我們透過 window.location.pathname 取得目前頁面的路徑,並轉成小寫以避免大小寫不一致問題。接著使用正則表達式移除路徑尾端多餘的斜線,確保 /a/b//a/b 被視為相同路徑。若路徑為空字串,則設定為根目錄 /

let currentPath = window.location.pathname.toLowerCase();
currentPath = currentPath.replace(/\/+$|\/$/, "");
if (currentPath === "") currentPath = "/";

選取側邊欄連結並逐一比對

使用 document.querySelectorAll 選取所有帶有 .anchor-links .link 的連結元素。對每個連結,我們先取得 href 屬性,並使用 URL 物件將相對路徑轉成絕對路徑,確保比對時不會因為相對路徑造成錯誤。

const links = document.querySelectorAll(".anchor-links .link");
links.forEach(link => {
  const href = link.getAttribute("href");
  if (!href) return;
  const url = new URL(href, window.location.origin);
  let hrefPath = url.pathname.toLowerCase();
  hrefPath = hrefPath.replace(/\/+$/, "");
  if (hrefPath === "") hrefPath = "/";

  if (hrefPath === currentPath) {
    link.classList.add("active");
  }
});

為何要使用 URL 物件?

使用 new URL(href, window.location.origin) 可以將相對路徑(例如 ../page)轉換成完整的絕對路徑,避免直接比對相對路徑時因基底路徑不同而失準。這是實務中常見的路徑比對技巧。

實際應用場景

  • 多層次導覽列或側邊欄,需自動標示當前頁面。
  • 靜態網站或沒有後端模板渲染的情況下,前端動態控制導覽狀態。

延伸優化方向

  • 可加入支援查詢字串(query string)或 hash 的比對。
  • 支援部分路徑匹配,例如 /blog 下所有頁面都標示為 active。
  • 將功能封裝成函式,方便重複使用。

常見問題與注意事項

  • 確保側邊欄連結的 href 屬性正確,避免空值或錯誤路徑。
  • 不同瀏覽器對 URL 物件支援度良好,但在非常舊版本可能需 polyfill。
  • 若網站有使用前端路由(如 SPA),此方法需配合路由狀態更新。

完整程式碼

document.addEventListener("DOMContentLoaded", function () {
    // 目前頁面的 path,例如 /investor-relations/corporate-governance/
    let currentPath = window.location.pathname.toLowerCase();
    // 移除結尾多餘的斜線(/a/b/ -> /a/b)
    currentPath = currentPath.replace(/\/+$/, "");
    if (currentPath === "") currentPath = "/";

    const links = document.querySelectorAll(".anchor-links .link");

    links.forEach(link => {
        const href = link.getAttribute("href");
        if (!href) return;

        // 轉成絕對網址再拿 pathname,避免相對路徑問題
        const url = new URL(href, window.location.origin);
        let hrefPath = url.pathname.toLowerCase();
        hrefPath = hrefPath.replace(/\/+$/, "");
        if (hrefPath === "") hrefPath = "/";

        // ✅ 完整匹配才加 active
        if (hrefPath === currentPath) {
            link.classList.add("active");
        }
    });
});