文章目录
- 前言
- 一、示例图
- 二、实现过程
- 1.需求解析
- 2.HTML结构
- 3.CSS样式
- 4.JS行为
- 总结
一、示例图
二、实现过程
1.需求解析
- 当用户点击切换tab栏时,相应的样式以及对应的文字都应做相应改变
- 且当用户点击某元素时,其他元素的样式以及内容应该是无效果状态
2.HTML结构
<!-- 第一个tab -->
<div class="tab">
<div class="nav">
<a href="javascript:;" class="hover">公司新闻</a>
<a href="javascript:;">公司动态</a>
<a href="javascript:;">行业新闻</a>
</div>
<div class="nav_con">
<div>公司新闻-show</div>
<div>公司动态-show</div>
<div>行业新闻-show</div>
</div>
</div>
<br /><br /><br />
<!-- 第二个tab -->
<div class="tab">
<div class="nav">
<a href="javascript:;" class="hover">大学</a>
<a href="javascript:;">中学</a>
<a href="javascript:;">小学</a>
</div>
<div class="nav_con">
<div>大学内容</div>
<div>中学内容</div>
<div>小学内容</div>
</div>
</div>
<!-- 第三个tab -->
<div class="tab">
<div class="nav">
<a href="javascript:;" class="hover">大学</a>
<a href="javascript:;">中学</a>
<a href="javascript:;">小学</a>
</div>
<div class="nav_con">
<div>大学内容</div>
<div>中学内容</div>
<div>小学内容</div>
</div>
</div>
3.CSS样式
<style type="text/css">
a {
text-decoration: none;
}
.nav a {
display: block;
width: 160px;
height: 35px;
line-height: 35px;
text-align: center;
background: #DCDCDC;
color: #666;
float: left;
margin-right: 10px;
}
.nav a.hover {
background: blue;
color: #fff;
}
.nav_con {
clear: both;
}
.nav_con div {
display: none;
}
.nav_con div:nth-child(1) {
display: block;
}
</style>
4.JS行为
这一部分的实现过程比较重要,主要利用了事件委派以及事件对象等相关知识点实现,
实现思路——
- 首先要做到的是当每个 tab 有自己独立的事件,也就是说在单击当前 tab 栏时不应影响到其他 tab,那么如何做到呢?
- 可以先获取每个tab栏的父元素也就是 nav ,随后通过给当前 nav 设置单击监听事件,虽然单击事件最后应该是 nav 下的具体子元素完成,但使用事件委派的方法只要给其父元素的方法设置单击事件可减少事件绑定次数。
- 随后获取当前 nav 下的所有子元素并进行遍历,在遍历的过程中利用排他思想设置所有子元素的样式,记得设置当前子元素的自定义属性(setAttribute), 因为还要实现当前子元素下对应的兄弟元素列表(也就是本案例中的内容描述区域 nav_con)
- 获取自定义属性(getAttribute),并获取当前子元素下对应的兄弟元素列表(e.target.parentNode.nextElementSibling.children;)并获取该列表随即进行遍历该列表并与排他思想结合设置相应样式。
<!-- 事件委派 -->
<script type="text/javascript">
var navNodes = document.querySelectorAll(".nav");
for (var i = 0; i < navNodes.length; i++) {
//通过委派给父亲添加单击事件
navNodes[i].addEventListener('click', function (e) {
//获得当前节点的父节点,通过父节点获得所有的所有nav a下面的子节点
var navs = e.target.parentNode.children;
for (var j = 0; j < navs.length; j++) {
navs[j].className = "";
//给每一个子节点加上自定义属性:index
navs[j].setAttribute("index", j);
}
//获取当前被点击的nav as上面的属性index
var thisIndex = e.target.getAttribute("index");
//当前元素的父级元素(nav),然后再获得下一个兄弟元素(nav_con),找他所有的子元素(nav_con div)
var nav_cons = e.target.parentNode.nextElementSibling.children;
//让所有nav_con div影藏
for (var j = 0; j < nav_cons.length; j++) {
nav_cons[j].style.display = "none";
}
//当前的nav_con div显示
nav_cons[thisIndex].style.display = "block";
//当前的节点 加上hover样式
e.target.className = "hover";
})
}
</script>