前言
Tab 功能是前端常見的 UI 元件,許多框架都提供現成的實作,但若想深入理解其背後的運作原理,使用原生 JavaScript 自行實作是一個很好的練習。本文適合有基礎程式能力的工程師或自學者,透過範例拆解,了解如何控制元素顯示與切換樣式。
HTML 結構說明
Tab 功能主要由兩部分組成:控制按鈕與內容區塊。
- 按鈕部分使用
<a>標籤,href="javascript:void(0)"用來阻止預設跳轉行為。 - 按鈕會帶有
tablink及特定的testbtnclass,方便 JavaScript 操作。 onclick事件會呼叫openClass(event, 'classX'),帶入事件物件與對應內容區塊的 id。- 內容區塊以
id和class="class"標示,對應按鈕的參數,方便顯示與隱藏。
<div class="bar-block">
<div class="container">
<h5>選單</h5>
<a href="javascript:void(0)" class="bar-item button tablink testbtn" onclick="openClass(event, 'class1')">教學1</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class2')">教學2</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class3')">教學3</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class4')">教學4</a>
</div>
</div>
<div id="class1" class="container class">
教學1內容
</div>
<div id="class2" class="container class">
教學2內容
</div>
<div id="class3" class="container class">
教學3內容
</div>
<div id="class4" class="container class">
教學4內容
</div>
JavaScript 功能解析
openClass 函式負責切換 Tab 的顯示狀態與按鈕樣式:
- 使用
document.getElementsByClassName("class")取得所有內容區塊,並將它們隱藏(display = "none")。 - 取得所有按鈕元素
tablinks,並移除所有按鈕的red樣式,確保只有一個按鈕被標示為選中。 - 根據傳入的
className參數,將對應內容區塊顯示(display = "block")。 - 對當前點擊的按鈕元素新增
redclass,標示為選中狀態。
function openClass(evt, className) {
var i, x, tablinks;
x = document.getElementsByClassName("class");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("red");
}
document.getElementById(className).style.display = "block";
evt.currentTarget.classList.add("red");
}
// 頁面載入後自動觸發第一個帶有 testbtn 的按鈕點擊
var mybtn = document.getElementsByClassName("testbtn")[0];
mybtn.click();
實際應用與延伸
- 可依需求調整
redclass 的 CSS 樣式,達到不同的選中效果。 - 若 Tab 數量動態產生,需確保事件綁定正確。
- 可改用事件代理方式優化效能。
- 進階可結合動畫效果,提升使用者體驗。
常見坑點
- 忘記阻止
<a>的預設行為會導致頁面跳轉。 - 未正確移除其他按鈕的選中樣式,導致多個 Tab 同時被標示。
- 忘記預設觸發第一個 Tab,頁面初始狀態會空白。
完整程式碼
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>原生 JavaScript Tab 功能</title>
<style>
.red { color: red; font-weight: bold; }
.class { display: none; }
</style>
</head>
<body>
<div class="bar-block">
<div class="container">
<h5>選單</h5>
<a href="javascript:void(0)" class="bar-item button tablink testbtn" onclick="openClass(event, 'class1')">教學1</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class2')">教學2</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class3')">教學3</a>
<a href="javascript:void(0)" class="bar-item button tablink" onclick="openClass(event, 'class4')">教學4</a>
</div>
</div>
<div id="class1" class="container class">
教學1內容
</div>
<div id="class2" class="container class">
教學2內容
</div>
<div id="class3" class="container class">
教學3內容
</div>
<div id="class4" class="container class">
教學4內容
</div>
<script>
function openClass(evt, className) {
var i, x, tablinks;
x = document.getElementsByClassName("class");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("red");
}
document.getElementById(className).style.display = "block";
evt.currentTarget.classList.add("red");
}
var mybtn = document.getElementsByClassName("testbtn")[0];
mybtn.click();
</script>
</body>
</html>