目录
选项卡_0.0
需求:
+ 点击哪一个'按钮'的时候, 切换对应的'按钮'高亮, 和盒子显示
+ 例子: 当你点击 1号 '按钮' 的时候
=> 1号'按钮'有 active 类名, 2号'按钮'和3号'按钮'没有 active 类名
=> 1号'盒子'有 active 类名, 2号'盒子'和3号'盒子'没有 active 类名
+ 例子: 当你点击 2号按钮 的时候
=> 2号'按钮'有 active 类名, 1号'按钮'和3号'按钮'没有 active 类名
=> 2号'盒子'有 active 类名, 1号'盒子'和3号'盒子'没有 active 类名
HTML _ 结构部分 :
<div class="box">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ol>
</div>
CSS _ 样式部分 :
* {
margin: 0;
padding: 0;
}
ul, ol, li {
list-style: none;
}
.box {
width: 500px;
height: 300px;
border: 2px solid pink;
margin: 50px auto;
display: flex;
flex-direction: column;
}
.box > ul {
height: 60px;
border-bottom: 2px solid pink;
display: flex;
}
.box > ul > li {
flex: 1;
background-color: skyblue;
color: #fff;
font-size: 26px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.box > ul > li.active {
background-color: orange;
}
.box > ol {
flex: 1;
position: relative;
}
.box > ol > li {
width: 100%;
height: 100%;
background-color: purple;
position: absolute;
left: 0;
top: 0;
font-size: 100px;
justify-content: center;
align-items: center;
display: none;
}
.box > ol > li.active {
display: flex;
}
JS 代码实现 :
1. 获取元素
=> btns, 表示所有 ul 下面的 li, 也就是所有"按钮"
=> boxs, 表示所有 ol 下面的 li, 也就是所有"盒子"
2. 绑定点击事件
=> 给 btns 里面的每一个"按钮", 绑定点击事件
=> 因为点击每一个"按钮"的时候, 执行切换操作
3. 拿到我点击的这个 li 的索引是多少
=> 当你点击 1号 "按钮"的时候, 1号"按钮"和1号"盒子"都有 active
=> 你需要知道你点击的这个 li 的索引是多少
=> [ btn1, btn2, btn3, btn4 ]
[ box1, box2, box3, box4 ]
=> 在循环绑定点击事件的时候
-> 顺便把索引记录在元素身上
4. 切换类名
=> 把所有元素的类名都去掉, 单独给我当前点击的这一个加上
底码 :
// 1. 获取元素
var btns = document.querySelectorAll('ul > li')
var boxs = document.querySelectorAll('ol > li')
// 2. 绑定事件
// 外层循环的目的 :
// 给每一个 按钮 添加点击事件, 并且向每一个按钮身上绑定一个自定义属性, 用来记录索引
for (var i = 0; i < btns.length; i++) {
// 3-1. 顺便给每一个元素添加一个自定义属性, 记录该元素的索引
btns[i].dataset.index = i
// 2-2. 给每一个按钮绑定点击事件
btns[i].onclick = function () {
// 在点击事件内, i 不好使(当你点击时 , i 一直为 3)(后引用注释讲解)
// (解决)在点击事件内, this 表示绑定事件的这个 按钮, 也就是我点击的这个按钮
// 3-2. 拿到你点击的这个元素身上的 自定义属性 data-index
// this 我点击的这个元素
// dataset 获取元素的 H5 自定义属性
var index = this.dataset.index - 0 // 代替在点击函数内不好使了的 i 值
// 用记录的 index 表示索引值(此时 index 为字符串类型 , 转换为数值类型方便使用)
// 4-1. 给 btns 内所有元素去掉类名
for (var j = 0; j < btns.length; j++) {
btns[j].classList.remove('active')
}
// 4-2. 给 boxs 内的所有元素去掉类名
for (var k = 0; k < boxs.length; k++) {
boxs[k].classList.remove('active')
}
// 4-3. 给 btns 里面和 boxs 里面 的第 index 个加上类名
btns[index].classList.add('active')
boxs[index].classList.add('active')
}
}
> 目前这个循环的目的 : 为了给每一个 按钮(btns[i]) 绑定点击事件
开始循环 :
i === 0
btns[0].onclick = function a() { console.log(i) }
-> 事件处理函数 a 是绑定在哪一个元素身上的 ? 是 btns[0]
-> 事件处理函数 a 内的 "这个" 就是 btns[0]
i === 1
btns[1].onclick = function () { console.log(i) }
i === 2
btns[2].onclick = function () { console.log(i) }
i === 3
循环结束当你开始点击的时候
+ 循环已经结束了
+ 循环结束以后, i 就是 length , 所以 i 就会一直是 3 , 无法使用了
优化 :
// 1. 获取元素
var btns = document.querySelectorAll('ul > li')
var boxs = document.querySelectorAll('ol > li')
// 2. 绑定事件
for (var i = 0; i < btns.length; i++) {
// 3-1. 顺便给每一个元素添加一个自定义属性, 记录该元素的索引
btns[i].dataset.index = i
// 2-2. 给每一个按钮绑定点击事件
btns[i].onclick = function () {
// 3-2. 拿到你点击的这个元素身上的 自定义属性 data-index
var index = this.dataset.index - 0
// 4-1. 给 btns 内所有元素去掉类名
// 4-2. 给 boxs 内的所有元素去掉类名
// 问题1: btns 的 length 和 boxs 的 length 是否一样 ?
// btns.length === boxs.length
// 问题2: 为什么要用 for 循环遍历数组或者伪数组吗 ?
// 因为 循环 可以提供一组有规律的数字
// 因为 数组或者伪数组 的排列就是按照索引排列, 索引就是一组有规律的数字
// 使用循环控制变量来充当索引, 访问数组或者伪数组内的每一个成员
for (var j = 0; j < btns.length; j++) {
btns[j].classList.remove('active')
boxs[j].classList.remove('active')
}
// 4-3. 给 btns 里面和 boxs 里面 的第 index 个加上类名
btns[index].classList.add('active')
boxs[index].classList.add('active')
}
}
底码优化精简版:
// 获取元素
var btns = document.querySelectorAll('ul > li')
var boxs = document.querySelectorAll('ol > li')
for (var i = 0; i < btns.length; i++) {
// 给每一个元素添加一个自定义属性, 记录该元素的索引
btns[i].dataset.index = i
// 给每一个按钮绑定点击事件
btns[i].onclick = function () {
// 拿到你点击的这个元素身上的 自定义属性 data-index
var index = this.dataset.index - 0
// 给 btns 和 boxs 内所有元素去掉类名
for (var j = 0; j < btns.length; j++) {
btns[j].classList.remove('active')
boxs[j].classList.remove('active')
}
// 给 btns 里面和 boxs 里面 的第 index 个加上类名
btns[index].classList.add('active')
boxs[index].classList.add('active')
}
}
forEach 实现选项卡 :
// 获取元素
var btns = document.querySelectorAll('ul > li')
var boxs = document.querySelectorAll('ol > li')
btns.forEach(function (item, index) {
// item 就是 btns 内的每一个
item.onclick = function () {
// 拿到你点击的这个 item 对应的索引
for (var i = 0; i < btns.length; i++) {
btns[i].classList.remove('active')
boxs[i].classList.remove('active')
}
// 给 index 对应的加上 active
btns[index].classList.add('active')
boxs[index].classList.add('active')
}
})