纯 JavaScript 实现 Tab 标签页切换的四种方式与最佳实践

沈知远
沈知远
发布时间:2026-10-13| 6人浏览过
原创

探讨如何使用原生 JavaScript 实现灵活的 Tab 标签页切换功能,分析从基础 DOM 操作到最优事件处理方案的演进过程。

Tab 切换功能的演进与原理

在前端开发中,Tab 切换是常见的 UI 交互组件。实现这一功能的核心在于:当用户触发某个标签(Tab)时,更新其样式状态为“选中”,同时隐藏其他所有标签对应的内容区域,并显示当前选中标签的内容区域。以下将逐步拆解四种由简入繁的实现思路。

方法一:基于 ID 的直接操控(不推荐)

最直观但冗余度最高的方式是为每个 Tab 和内容块分配唯一的 id,并在 HTML 中内联绑定具体的事件函数。这种方式虽然逻辑简单,但导致 HTML 结构与 JS 逻辑高度耦合,缺乏扩展性。

第1步:编写结构化的 HTML

创建表头容器包含多个 h2 元素作为 Tab 按钮,内容容器包含对应的子 div。

<div class="tab-head">
  <h2 id="tab1" onmouseover="changeTab1()" class="selected">1</h2>
  <h2 id="tab2" onmouseover="changeTab2()">2</h2>
  <h2 id="tab3" onmouseover="changeTab3()">3</h2>
</div>
<div class="tab-content">
  <div id="c1" class="show">content1</div>
  <div id="c2">content2</div>
  <div id="c3">content3</div>
</div>

第2步:配置 CSS 样式

利用 CSS 控制默认隐藏和选中状态的显示。

h2 {
  border-top: solid cornflowerblue 1px;
  border-left: solid cornflowerblue 1px;
  width: 50px;
  height: 25px;
  margin: 0;
  float: left;
  text-align: center;
}
.tab-content {
  border: solid cornflowerblue 1px;
  width: 152px;
  height: 100px;
}
.tab-content div {
  display: none;
}
.selected {
  background-color: cornflowerblue;
}
.tab-content .show {
  display: block;
}

第3步:编写分散的 JS 逻辑

获取各元素引用,并为每个 Tab 单独编写切换函数。随着 Tab 数量增加,代码量呈线性增长。

var tab1 = document.getElementById('tab1'),
tab2 = document.getElementById('tab2'),
tab3 = document.getElementById('tab3'),
c1 = document.getElementById('c1'),
c2 = document.getElementById('c2'),
c3 = document.getElementById('c3');
function changeTab1() {
  tab1.className = 'selected';
  tab2.className = '';
  tab3.className = '';
  c1.className = 'show'
  c2.className = '';
  c3.className = '';
}
function changeTab2() { /* 逻辑类似... */ }
function changeTab3() { /* 逻辑类似... */ }

方法二:基于索引参数的批量循环

此方法通过数组下标索引来统一管理状态。只需定义一个通用函数 changeTab(index),即可消除重复的代码块,但仍需在 HTML 中手动指定数字参数。

第1步:简化 HTML 结构

移除不必要的 id,直接使用 onmouseover="changeTab(N)" 传递序号。

<div class="tab-head">
  <h2 onmouseover="changeTab(0)" class="selected">1</h2>
  <h2 onmouseover="changeTab(1)">2</h2>
  <h2 onmouseover="changeTab(2)">3</h2>
</div>
<div class="tab-content">
  <div class="show">content1</div>
  <div>content2</div>
  <div>content3</div>
</div>

第2步:优化 JS 核心逻辑

首先收集所有的 Tab 节点和内容节点集合,然后在函数内部通过遍历循环匹配当前索引 i === index 来处理样式切换。

var tabs = document.getElementsByClassName('tab-head')[0].getElementsByTagName('h2'),
contents = document.getElementsByClassName('tab-content')[0].getElementsByTagName('div');
function changeTab(index) {
  for(var i = 0, len = tabs.length; i < len; i++) {
    if(i === index) {
      tabs[i].className = 'selected';
      contents[i].className = 'show';
    } else {
      tabs[i].className = '';
      contents[i].className = '';
    }
  }
}

方法三:基于 this 指针的精确匹配

为了摆脱对固定数字索引的依赖,可以将 this 指针直接传递给函数。这种方法在逻辑判断上更加语义化,无需关心顺序编号是否连续或变动。

第1步:HTML 传递对象引用

将事件绑定改为传递触发事件的当前 DOM 对象 this。

<h2 onmouseover="changeTab(this)" class="selected">1</h2>

第2步:修改 JS 判断条件

在 changeTab(tab) 函数中,通过 tabs[i] === tab 来判断是否为当前点击的对象。

function changeTab(tab) {
  for(var i = 0, len = tabs.length; i < len; i++) {
    if(tabs[i] === tab) {
      tabs[i].className = 'selected';
      contents[i].className = 'show';
    } else {
      tabs[i].className = '';
      contents[i].className = '';
    }
  }
}

方法四:基于事件绑定的解耦方案(最佳实践)

这是最推荐的进阶写法。完全移除了 HTML 中的内联 JS 代码,实现了 HTML 结构、CSS 表现与 JS 行为的彻底分离。通过自执行函数统一为所有 Tab 注册鼠标事件监听器。

第1步:清理 HTML 中的事件属性

HTML 仅保留类名和文本内容,不再包含任何 JS 逻辑标记。

<div class="tab-head">
  <h2 class="selected">1</h2>
  <h2>2</h2>
  <h2>3</h2>
</div>

第2步:封装独立的事件回调函数

定义全局函数 showTab(),在该函数内部,this 始终指向触发事件的 DOM 元素。因此可以直接用 tabs[i] === this 进行比对。

function showTab() {
  for(var i = 0, len = tabs.length; i < len; i++) {
    if(tabs[i] === this) {
      tabs[i].className = 'selected';
      contents[i].className = 'show';
    } else {
      tabs[i].className = '';
      contents[i].className = '';
    }
  }
}

第3步:自动挂载事件监听

利用立即执行函数(IIFE)在页面加载后自动遍历所有 Tab 节点,将 showTab 函数绑定到每个元素的 onmouseover 事件中。

var tabs = document.getElementsByClassName('tab-head')[0].getElementsByTagName('h2'),
contents = document.getElementsByClassName('tab-content')[0].getElementsByTagName('div');
(function changeTab(tab) {
  for(var i = 0, len = tabs.length; i < len; i++) {
    tabs[i].onmouseover = showTab;
  }
})();

总结

虽然上述第四种方式实现了完美的解耦,但在实际现代前端工程开发中,更推荐使用 addEventListener 替代旧式的 onmouseover 属性绑定,以支持事件冒泡和多监听器共存。此外,若业务逻辑复杂,建议结合 ClassList API (classList.add/remove) 替代直接设置 className,以避免意外覆盖原有的其他类名。以上就是纯 JavaScript 实现 Tab 标签页切换的详细内容,更多关于 DOM 操作与事件处理的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。