选项卡
选项卡在很多项目中都有用到,下面是我用原生js做的选项卡,如有不足,望指正。
html结构与样式
头部导航采用flex布局,等宽分布li元素。设置颜色是为了区分界限。
内容部分宽高占满剩余的空间,每个内容块宽高100%。
通过display属性让选中项内容显示,其他项内容隐藏。
css中的on样式:选中的那一项,增加的样式(头部li元素)。
css中的show样式:选中的那一项的内容,增加的样式(内容的div元素,show用来显示此元素)。
思路:在鼠标点击(或经过)时,通过for循环,清空所有li元素和内容div元素的样式(on和show),在for后面给当前选中项的头部li元素加on样式,给内容div元素增加show样式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>选项卡</title>
<style>
*{
margin: 0;
padding:0;
list-style:none;
}
.box{
width: 400px;
height: 250px;
border: 1px solid #000;
box-shadow: 0 0 10px 4px #ccc;
margin: 200px auto;
}
.title_list{
width: 100%;
display: flex;
}
.title_list li{
flex-grow: 1;
text-align: center;
height: 40px;
line-height: 40px;
background: #8bdaf3;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.title_list li:nth-of-type(2n){
background: #cc9c4f;
}
.content{
height: 210px;
width: 100%;
}
.content div{
width: 100%;
height: 100%;
/*display: none;*/
}
.on{
background: red!important;
color:#fff;
}
.show{
display: block!important;
}
</style>
</head>
<body>
<div class="box">
<ul class="title_list">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<div class="content">
<div>内容1</div>
<div>内容2</div>
<div>内容3</div>
</div>
</div>
</body>
</html>
效果图
js部分
将.content div样式中的注释去掉,刷新后所有内容div都隐藏了。接下来编写js代码:
<script language="JavaScript" type="text/javascript">
<!--
var title_list = document.getElementsByClassName('title_list')[0];
var content = document.getElementsByClassName('content')[0];
var len = title_list.children.length; //获取项的个数
var num = 0; //用来连接头部与内容的变量
title_list.children[num].className = 'on'; //设置默认选中的头部
content.children[num].className = 'show'; //设置默认选中的内容
function clickEvent() {
for(var i=0;i<len;i++){
title_list.children[i].index = i; //给每个头部li元素增加一个index属性,通过这个值来对应内容
title_list.children[i].onclick = function () { //给每个li元素增加点击事件
for(var j=0;j<len;j++){ //通过for循环清空on和show样式
title_list.children[j].className = '';
content.children[j].className = ''
}
num = this.index; //this为点击的当前li元素,将他的index赋值给num
this.className = 'on'; //当前的li元素增加on样式
content.children[num].className = 'show' //num此时为对应li元素的下标,将对应的内容div设置css样式show
}
}
}
clickEvent()
-->
</script>
一个简单的选项卡就完成了。
对于index这块,如果第一层for循环使用let而不是var,可以不需要index和num来做头部与内容的连接。使用var时,在点击的事件函数得到的i一直是len,使用let时,得到的是对应li元素的序号。
修改部分的代码:
function clickEvent() {
for(let i=0;i<len;i++){ //这里var变成了let
title_list.children[i].onclick = function () { //给每个li元素增加点击事件
for(var j=0;j<len;j++){ //通过for循环清空on和show样式
title_list.children[j].className = '';
content.children[j].className = ''
}
this.className = 'on'; //当前的li元素增加on样式
content.children[i].className = 'show' //i对应li元素的下标,将对应的内容div设置css样式show
}
}
}
通过数据来渲染选项卡
选项卡很多时候都是要改的,如果把html结构固定,不利于维护。
下面是通过数据来渲染选项卡:
html结构如下:
<div class="box">
<ul class="title_list"></ul>
<div class="content"></div>
</div>
js代码如下:
<script language="JavaScript" type="text/javascript">
<!--
var title_list = document.getElementsByClassName('title_list')[0];
var content = document.getElementsByClassName('content')[0];
var tabData = [ //数据
{
title:'选项1',
content:'<p>这是第一个选项的内容</p>'
},
{
title:'选项2',
content:'<p>这是第二个选项的内容</p>'
},
{
title:'选项3',
content:'<p>这是第三个选项的内容</p>'
},
{
title:'选项4',
content:'<p>这是第四个选项的内容</p>'
}
];
var titleStr = '';
var contentStr = '';
var len = tabData.length;
var num = 0;
for(var i=0;i<len;i++){ //通过for循环增加头部li和内容div
titleStr += `<li index=${i}`+`>${tabData[i].title}</li>`; //这里使用了反引号,属于es6的内容,使用变量的方法${这里是变量},如果不熟悉也可以使用引号的方法。
contentStr += `<div>${tabData[i].content}</div>`;
}
title_list.innerHTML = titleStr;
content.innerHTML = contentStr;
title_list.children[num].className = 'on';
content.children[num].className = 'show';
title_list.onclick = function (ev) { //通过事件委托处理事件
var ev = ev||event; //做火狐兼容
if(ev.target.tagName.toLowerCase()=='li'){ //判断所点击的事件源的节点是否是li,toLowerCase()是将字符串转成成小写。
for(var j=0;j<len;j++){ //清空样式
title_list.children[j].className = '';
content.children[j].className = ''
}
num = parseInt(ev.target.getAttribute('index'));//获取当前事件源的自定义属性index,转换成数字类型
ev.target.className = 'on'; //设置样式
content.children[num].className = 'show'
}
}
-->
</script>