前言:在电商平台我们经常能看到这样的切换效果,如何用原生的JS代码来实现这样的功能呢?
1.思路分析:排他思想
-
鼠标移入:显示自身样式,隐藏其他样式.同时获得自身的索引或者id
(图片较大,所以只写了简单的盒子来替代,核心思想不变)
2.书写顺序
1.获取元素
2.注册事件
3.事件处理
JS代码比较简单,直接添加到html结构即可
HTML,CSS部分:结构比较简单
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>tab栏切换</title>
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.box {
width: 400px;
height: 300px;
border: 1px solid #ccc;
margin: 100px auto;
}
.hd {
height: 45px;
}
.hd span {
display: inline-block;
/*将行内元素转换成行内块元素,宽高才起作用*/
width: 90px;
background-color: green;
line-height: 45px;
text-align: center;
cursor: pointer;
}
.hd span.current {
/*交集选择器,标签指定式选择器*/
background-color: aqua;
/*紫色*/
}
.bd li {
height: 255px;
display: none;
/*设置隐藏*/
}
.bd li.current {
display: block;
/*显示*/
}
</style>
</head>
<body>
<div class="box" id="box">
<div class="hd">
<span class="current">体育</span>
<span>娱乐</span>
<span>新闻</span>
<span>综合</span>
</div>
<div class="bd">
<ul id="list">
<li class="current">我是体育模块1111111111111111111111111111111</li>
<li>我的娱乐模块222222222222222222222</li>
<li id="li3">我是新闻模块333333333333333333333333333333</li>
<li>我是综合模块44444444444444444444444444444444444</li>
</ul>
</div>
</div>
</body>
</html>
JS关键点:给每一个元素设置自定义的索引,通过索引来确定关系
1.获取元素(通过类名获取返回的是一个伪数组,取下标才能得到元素)
//1.获取元素
var hd = document.getElementsByClassName('hd')[0];
var spanList = hd.getElementsByTagName('span'); //头部span列表
var ul = id('list'); //模块ul
var liList = ul.getElementsByTagName('li'); //具体模块列表
2.事件注册和事件处理
//2.遍历头部span列表
for (var i = 0; i < spanList.length; i++) {
//2.1 给每一个span标签添加一个自定义index
spanList[i].setAttribute('index', i);
//2.2给每一个span标签添加点击事件
spanList[i].onmouseover = function () {
//3: 点击span标签,自身样式发生变化,对应下标的li模块显示
//排他思想去除其他span的样式,并且隐藏其他模块li
//3.1 设置自身样式
this.className = 'current';
//3.2 显示对应下标的模块li
var index = this.getAttribute('index');
liList[index].style.display = 'block';
//3.3 排他思想去除其他span的样式,并且隐藏其他模块li
for (var j = 0; j < spanList.length; j++) {
if (spanList[j] != this) {
spanList[j].className = ''; //自身类名清空
liList[j].style.display = 'none'; //对应j下标的模块li标签隐藏
}
}
}
}
ES6 let语法的块级作用域
for (let i = 0; i < spanList.length; i++) {
spanList[i].onmouseover = function () {
this.className = 'current';
liList[i].style.display = 'block';
for (let j = 0; j < spanList.length; j++) {
if (spanList[j] != this) {
spanList[j].className = ''; //自身类名清空
liList[j].style.display = 'none'; //对应j下标的模块li标签隐藏
}
}
}
}
如果使用let,声明的变量仅在块级作用域内有效,每一次for设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。所以不需要再设置索引