原生JavaScript实现自适应高度Tab选项卡
本文提供使用原生 JavaScript 构建自适应高度 Tab 选项卡的解决方案,通过 DOM 操作和 CSS 类切换实现无依赖的交互逻辑。
核心原理与目标
传统的 Tab 选项卡通常有固定高度或需要额外处理 overflow。本方案的核心在于利用 display: block/none 控制内容区域的可见性,配合 CSS 动态调整容器高度,从而适配不同内容的实际尺寸。我们需要完成以下三个主要步骤:获取 DOM 元素、绑定点击事件、管理选中状态的类名切换。
HTML 结构与 CSS 准备
为了实现该功能,页面需要包含一个包含标签页(Tabs)和内容区域(Panels)的结构。假设 HTML 结构如下:
<div id="disDiv">
<div id="content">
<ul>
<li class="n hasClick">Tab 1</li>
<li class="n havtClick">Tab 2</li>
</ul>
<div class="panel n hasClick">Content 1</div>
<div class="panel n havtClick">Content 2</div>
</div>
</div>
CSS 方面,需要定义选中状态 .hasClick 和非选中状态 .havtClick。例如:
.hasClick {
display: block;
/* 其他选中样式 */
}
.havtClick {
display: none;
/* 其他非选中样式 */
}
第1步:编写辅助函数用于获取兄弟节点
为了在切换 Tab 时准确地清除其他项的状态并应用当前项状态,需要一个工具函数来获取指定元素的“兄弟”元素,即同一层级下具有相同类名的其他元素。这是原代码中的 getSiblingNode 函数的作用。
var getSiblingNode = function(className, elAr, el, not) {
className = " " + className + " ";
var Arr = [];
for (var i = 0, l = elAr.length; i < l; i++) {
// 排除当前元素,且类型必须为元素节点
if (elAr[i] != el && elAr[i].nodeType === 1) {
// 如果提供了className,检查是否匹配
if (className && (" " + elAr[i].className + " ").indexOf(className) > -1) {
Arr.push(elAr[i]);
} else if (!className) {
// 如果没有指定class,则收集所有同类型兄弟节点
Arr.push(elAr[i]);
}
}
}
return Arr;
};
- 目的:批量获取需要被重置状态的其他 Tab 项目。
- 参数说明:
elAr是节点数组,el是当前操作的目标节点,not用于控制是否严格匹配类名。
第2步:初始化点击事件与状态切换
接下来是实现逻辑的主体部分 runFn。它遍历所有的 Tab 按钮(通常是 <li>),并为每个按钮绑定点击事件。这里使用了闭包来确保每个按钮能正确引用其索引对应的内容区域。
var runFn = function(id, parentId) {
var elId = id;
var parentId = parentId;
// 获取内容容器
var contentEl = document.getElementById(elId);
// 获取所有的Tab按钮(假设为ul下的li)
var liEl = contentEl.getElementsByTagName("ul")[0].getElementsByTagName("li");
// 获取所有的内容面板
var divEl = document.getElementById(parentId).getElementsByTagName("div");
for (var i = 0, l = liEl.length; i < l; i++) {
// 使用闭包保存索引i
(function(i) {
var thisSibling = getSiblingNode("n", divEl, divEl[i], true);
liEl[i].onclick = function() {
// 1. 显示当前选中的内容面板
divEl[i].style.display = "block";
// 2. 设置当前Tab按钮的选中状态
this.className = "hasClick";
// 3. 获取其他未选中的Tab按钮兄弟节点
var divElSibling = getSiblingNode(null, liEl, liEl[i], false);
// 4. 隐藏所有内容面板中除当前以外的项
var thisPanelSibling = getSiblingNode("n", divEl, divEl[i], true);
for (var a = 0, b = thisPanelSibling.length; a < b; a++) {
thisPanelSibling[a].style.display = "none";
}
// 5. 清除其他Tab按钮的选中状态
for (var x = 0, y = divElSibling.length; x < y; x++) {
divElSibling[x].className = "havtClick";
}
};
})(i);
}
};
- 关键逻辑:每次点击只高亮当前
li和其对应的div,并将其余同类元素重置为默认样式。 - 注意:原代码中
divElSibling获取的是li数组,而thisSibling获取的是div数组,这在混合结构时需注意对应关系。
第3步:启动初始化
最后,在页面加载完成后执行初始化函数。由于现代浏览器推荐使用 DOMContentLoaded,但在兼容旧环境或使用原逻辑时,可挂载于 window.onload。
var slide = function() {
// id为内容区的ID,parentId为包裹整个选项卡的父容器ID
runFn("content", "disDiv");
};
window.onload = slide;
完成判断与维护建议
当页面刷新后,点击不同的 Tab 标签,对应的内容区域应能正确显示,且仅有选中项具备 hasClick 类名及其对应的 CSS 样式。其他项保持隐藏或非选中样式。
若在实际使用中遇到高度未自适应的情况,请检查 CSS 中是否设置了固定的 height 而非由内容撑开,或者确认 JS 是否正确清除了其他面板的 display 属性。此外,原代码使用的是字符串拼接类名的方式,若需更复杂的类名管理,建议使用 classList.add/remove API 以提升代码可读性和健壮性。
以上就是原生 JavaScript 实现自适应高度 Tab 选项卡的详细内容,更多关于前端 UI 交互组件的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









