javaScript练习(二):tab选项卡

时间:2021-12-02 17:12:27

tab选项卡,是一个非常常见的js展览效果,前天帮一个同学做了几个页面,用到了这个功能,现在闲下来对它进行一点总结,希望对向我一样的刚刚入门的初学者有一点帮助。

我们来想一下这个功能如何实现呢?
当鼠标点击标头时,下面相应的模块会跟着动,他们是一个整体么?其实并不是这样的,我来说一下最简单的原理:当你鼠标点击时,触发的效果是将非点击的模块display:none,点击的模块增加属性display:block;
这样一来就会让非点击的模块消失。

好了,现在看来是不是很简单呢?对,举个简单的例子,如下代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.tabSwitchparent{
position:relative;
height:200px;
width:324px;
}

.tabSwitchparent div{
position:relative;
float:left;
}

.tabSwitchTarget{
width:324px;
height:100px;
display:none;
border: solid 1px #666666;
z-index:1;
top:0;
}

.tabSwitch{
z-index:2;
top:1px;
}

.tabSwitch .on{
border: solid 1px #666666;
border-bottom: none;
background-color:#ffffff;
}

//用来表现标头被点击的css样式,本身的z轴偏移要比下面的模块高,并且背景为白,这样才可以把下面的border盖上。
</style>
<script>
window.onload=function(){
var tab1= document.getElementById("tabSwitch1");
var tab2=document.getElementById("tabSwitch2");
tab1.onclick=function(){ document.getElementsByClassName("tabSwitchTarget")[0].style.display="block";//将tab1变display:block同时要把tab2变成none,消失这个一定要理解,如果不变,一轮点击下来,两个都有了display:block属性,切记。
this.className="on";
tab2.className="";//这里同理。
}
tab2.onclick=function(){
document.getElementsByClassName("tabSwitchTarget")[0].style.display="none";
document.getElementsByClassName("tabSwitchTarget")[1].style.display="block";
this.className="on";
tab1.className="";
}
}//tab2 类似。
</script>
</head>
<body>
<div class="tabSwitchparent">
<div class="tabSwitch">
<div class="on" id="tabSwitch1">选项卡一</div>
<div id="tabSwitch2">选项卡二</div>
</div>
<div class="tabSwitchTarget" style="display:block;">内容一</div>
<div class="tabSwitchTarget">内容二</div>
</div>
</body>
</html

这个就是最简单的例子,效果如图。
javaScript练习(二):tab选项卡
看到这里,如果您觉得上面的那个例子很是幼稚的话,那么您一定有了一定的水平。没错,上面的那个例子只是一个最简单的原理展示,存在着很多的不足和缺点,下面我们一起来探讨一下。

之所以前端的起点和入门很低,是表现它的语言很是通俗,甚至在一些程序帝眼中,html5的三门语言都不能称为语言。因此很多非计算机专业的同学一样可以快速的适应这个还处于发展中的职业。但是,前端的中期和后期是一个非常漫长的过程,如果你接触过其他高级的语言,那么你会更好的领悟它,如果你没有接触过,那也没有关系,每看到一个效果就去自己思考如果这个效果给你来写,你要怎么第一时间完成,第一时间容错并使你的代码看上去更加的清爽。

哈哈,以上是我的老师说过的一段话,共勉吧。

缺点:这里的标头只有“选项一”和“选项二”两个,那么如果有更对的分类,你还要每一个分类都用一个变量来去获取么?每一次的点击,你都要完成这种笨重的改变display么?

这个思想的转变就是面向对象编程中的类的一种思想体现,把类似的东西抽象出来,写成一个通用的方法,下回用的时候只要调用就好了!也是这种“懒人”的思想,才出现了高效的jQuery!

这里不用jQuery的方法,好了不啰嗦了,我写了两个函数来完成了这个功能,

function getTypeElement(es,type){
var eslen=es.length,
i= 0,
eArr=[],
esl=null;
for(;i<eslen;i++){
esl=es[i];
if(esl.nodeName.replace("#","").toLowerCase()==type){
eArr.push(esl);
}
}
return eArr;
}//获取指定类型的节点

来看看这个函数,有两个参数,一个是要遍历的节点的范围性节点es,一般传入一个节点数组,如es.childNodes。另一个是要查找的节点类型type。

if条件句里面的那一长串又是干什么的呢?首先,你要了解nodeName这个方法会得到什么。它会返回一个节点的名称,如果是标签,就返回标签的名字,但是请注意(可以自己写写验证),返回的这个String是大写的标签名字(如,li返回LI),还有如果标签中间有text类型的东东(文本,空格,回车等),它会返回#text,为了提升性能并保证这个函数更有一般性,加了一个replace来去#,加了一个toLowerCase()来变成小写。

有了这个函数,就不用var 多个变量来操作了。

 function tabSwitch(e){
var divs=getTypeElement(e.childNodes,"div"),
l=divs.length,
i=0;
for(;i<l;i++){
divs[i].onclick=function(){
for(var ii=0;ii<l;ii++){
divs[ii].className="";
document.getElementById("tabSwitch"+(ii+1)).style.display="none";
}
this.className="on";
document.getElementById(this.getAttribute("data-targent")).style.display="block";
}
}
}
tabSwitch(document.getElementById("tabSwitch"));
};

这个函数,是用来“动”display的。基本思想,是每一次点击,把所有的节点都遍历设成display:none,之后在进行点击者的改变。
好了,来看看整个代码吧!

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>选项卡例子代码</title>
<style>
.tabSwitchParent{
position:relative;
width:324px;
}

.tabSwitchParent div{
position:relative;
float:left;
}

.tabSwitchTarget{
display:none;
left:0;
top:0;
z-index:1;
width:324px;
height:54px;
padding:5px;
border:solid 1px #ccc;
color:#666;
}

#tabSwitch{
z-index: 2;
top:1px;
}

#tabSwitch{
font-size:15px;
margin:0;
text-align:center;
cursor:pointer;
}

#tabSwitch .on{
border:solid 1px #ccc;
border-bottom: none;
background-color:#fff;
}

</style>
<script>
window.onload=function(){
function getTypeElement(es,type){
var eslen=es.length,
i= 0,
eArr=[],
esl=null;
for(;i<eslen;i++){
esl=es[i];
if(esl.nodeName.replace("#","").toLowerCase()==type){
eArr.push(esl);
}
}
return eArr;
}//获取指定类型的节点
function tabSwitch(e){
var divs=getTypeElement(e.childNodes,"div"),
l=divs.length,
i=0;
for(;i<l;i++){
divs[i].onclick=function(){
for(var ii=0;ii<l;ii++){
divs[ii].className="";
document.getElementById("tabSwitch"+(ii+1)).style.display="none";
}
this.className="on";
document.getElementById(this.getAttribute("data-targent")).style.display="block";
}
}
}
tabSwitch(document.getElementById("tabSwitch"));
};
</script>
</head>
<body>
<h2>Tab选项卡</h2>
<div class="tabSwitchParent">
<div id="tabSwitch">
<!---选项卡-->
<div data-targent='tabSwitch1' class="on">选项卡1</div>
<div data-targent='tabSwitch2'>选项卡2</div>
<div data-targent='tabSwitch3'>选项卡3</div>
</div>
<!---内容-->
<div class="tabSwitchTarget" style="display:block;color:#123323" id="tabSwitch1">选项卡1</div>
<div class="tabSwitchTarget" style="color:#123323" id="tabSwitch2">选项卡2</div>
<div class="tabSwitchTarget" style="color:#123323" id="tabSwitch3">选项卡3</div>
</div>
</body>
</html>

虽然我觉得这个代码并不是算法上最优的代码(因为这个每一次都要把所有的设为none,应该会有更好的算法,待我想出了更新这篇文章。)但是这个代码的可读行和使用性很好,如果你要添加新的分类,加新的对应注释下的div就行了。
(那个data-target是自定义属性,用来二级控制的~~)。

以上代码参考了一些资料,如《超实用的JavaScript代码段》电子工业出版社,这本书挺好的,但可能有些地方不是很规范(感觉作者是后台转过来的,当然也可能是我水平不够,推荐大家看看~~~~