前言
在多頁面網站中,常見需求是讓側邊欄或導覽列中的連結能自動標示當前所在頁面,提升使用者導覽體驗。這段程式碼示範如何透過 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");
}
});
});