前端_JS-选项卡(tab 切换)

目录

选项卡_0.0 

HTML _ 结构部分 :

 CSS _ 样式部分 :

JS 代码实现 :

底码 :

优化 : 

底码优化精简版:

forEach 实现选项卡 :


选项卡_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')
      }
    })

上一篇:Elasticsearch集群健康


下一篇:前端基础---使用普通背景图当按钮背景时出现的问题(以及背景简写)