效果展示:
# 初步实现
编写HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html> <html>
<head> <meta charset="utf-8"> <title>标签页切换</title> <link rel="stylesheet" href="./TabSwitch.css"> </head>
<body> <h1>标签页切换</h1>
<section class="tab-switch"> <div class="tabs"> <div class="tab">标签1</div> <div class="tab">标签2</div> <div class="tab">标签3</div> </div> <div class="panels"> <div class="panel">内容1 内容1 内容1 内容1 内容1 内容1 内容1</div> <div class="panel">内容2 内容2 内容2 内容2 内容2 内容2 内容2</div> <div class="panel">内容3 内容3 内容3 内容3 内容3 内容3 内容3</div> </div> <div class="tab-foot"> <button>确定</button> </div> </section>
<script src="./TabSwitch.js"></script> </body>
</html>
|
这里将整个标签部分包裹在tab-switch类的section中,其中三个div:标签(tabs)、内容(panels)和底栏(tab-foot)。现在为了方便测试,先手动添加三个页面。
制作CSS
- 整个section为纵向flex布局,标签页栏和底栏站上下,中间自动填充为内容;
- 标签页栏为横向flex布局,其中的元素自动均匀排布;
- 标签上面圆角
- 内容默认display为none,只有出现enable类的时候才显示,为了方便制作标签页切换效果;
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| html { font-size: 10px; }
.tab-switch { margin: 0 auto; height: 400px; width: 400px; display: flex; flex-flow: nowrap column; justify-content: space-between;
font-size: 1.6rem; }
.tabs { display: flex; flex-flow: nowrap row; overflow: auto; }
.tab { flex-grow: 1; text-align: center; line-height: 3; border-radius: 10px 10px 0 0; background-color: rgb(50,50, 50); color: white; }
.panels { flex: 1; background-color: rgb(38, 36, 46); color: white; }
.panel{ padding: 0 1rem; display: none; }
.panel.enable{ display: block; }
.tab-foot { background-color: rgb(50, 50, 50); }
.tab-foot button{ float: right; width: 20%; line-height: 2;
font-size: 1.6rem; border: none; background-color: rgb(77, 207, 77); color: white; }
|
JS实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const tabs = document.querySelectorAll('.tab'); const panels = document.querySelectorAll('.panel'); let choise = -1;
tabs.forEach((tab, index, arr) => { tab.index = index; tab.addEventListener('click', () => { tabClick(tab); }) })
let tabClick = function (tab) { if (tab.index === choise) return;
if (choise >= 0) panels[choise].classList.remove('enable'); let panel = panels[tab.index]; panel.classList.add('enable'); choise = tab.index; }
tabClick(tabs[0]);
|
现在就实现了标签点击切换内容显示的效果。
优化效果
现在标签还没反应,下面制作标签被选中等状态的不同效果。
1 2 3 4 5 6 7 8
| .tab:hover { background-color: rgb(70, 70, 70); }
.tab.enable { border-bottom: 2px solid orange; background-color: rgb(40, 40, 40); }
|
然后在js中也给tab添加enable类
1 2 3 4 5 6 7 8 9 10 11 12 13
| let tabClick = function (tab) { if (tab.index === choise) return;
if (choise >= 0) { panels[choise].classList.remove('enable'); tabs[choise].classList.remove('enable'); } panels[tab.index].classList.add('enable'); tab.classList.add('enable'); choise = tab.index; }
|
然后稍微优化一下tab就好了。
添加动态生成功能
我的需求是,根据输入的数组动态生成对应数量的标签页,现在来用js实现一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| let tabs = []; let panels = [];
const tabContainer = document.querySelector('.tabs'); const panelContainer = document.querySelector('.panels');
const tabNames = ['Tab1', '标签2', '2333333', '阿巴阿巴阿巴阿巴']; const tabContent = ['Tab1Tab1Tab1Tab1Tab1Tab1Tab1Tab1Tab1Tab1', '标签2标签2标签2标签2标签2标签2标签2标签2标签2标签2标签2', '233333333333333333333333333333333333333333333333333333', '阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴']; let choise = -1;
tabNames.forEach((tabName, index, arr) => { let tab = document.createElement('div'); tab.textContent = tabName; tab.classList.add('tab'); tabContainer.appendChild(tab); tabs.push(tab);
let panel = document.createElement('div'); panel.textContent = tabContent[index]; panel.classList.add('panel'); panelContainer.appendChild(panel); panels.push(panel); })
|
后面的绑定事件等都没变化,现在就可以生成选项卡以及内容了
资源
效果展示:https://1keven1.github.io/BlogSrc/WebGLRenderer/SimpleDemo.html
资源:https://github.com/1keven1/BlogSrc/tree/main/WebLearn/TabSwitch