2. DOM 事件基础(2) - 高阶函数、环境对象、排他思想、tab 栏切换实例

81 阅读3分钟

高阶函数

高阶函数 可以被简单的理解为函数的高级应用,JS 中函数可以被当成 来看待,基于这个特性实现函数的高级应用。

就是 JS 中的数据,如数值、字符串、对象等。

1. 函数表达式

关于函数表达式,之前的文章中有写过,这里简单提一下,函数表达式和普通函数并无本质上的区别:

    <script>
      let add = function (x, y) {
        return x + y
      }
      let test = add(3, 5)
      console.log(test)
    </script>

普通函数的声明与调用没有顺序限制,但建议先声明后调用

函数表达式必须要先声明再调用

2. 回调函数

如果将函数 A 当作参数来传递给函数 B 时,我们将函数 A 称为 回调函数

image.png

函数表达式 中,函数也是数据,函数表达式是把函数赋值给了变量;

回调函数 中,是把函数(回调函数)当作另一个函数的参数传递,回调函数的本质还是函数,只不过把它当成了参数使用;

使用匿名函数作为回调函数比较常见

环境对象简介

环境对象 指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境

函数的调用方式不同,this 指代的对象也不同;

可以使用 谁调用,this 就是谁 的粗略规则来判断 this 的指向;

直接调用函数,其实就相当于是 window.函数 ,所以这里 this 指代的就是 window :

    <script>
      function add(x, y) {
        console.log(this)
        return x + y
      }
      add(3, 8)
    </script>

image.png

排他思想

排他思想 :当前元素为 A 状态,其他元素为 B 状态。

简单来说就是,使用 for 循环,干掉所有人,然后通过 this 或下标找到自己或者对应元素,复活他自己

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
  </head>
  <style>
    button {
      border: 0;
    }
    .bgc {
      background-color: aqua;
    }
  </style>
  <body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>

    <script>
      let btns = document.querySelectorAll('button')

      for (let i = 0; i < btns.length; i++) {
        btns[i].addEventListener('click', () => {
          // 干掉所有人
          for (let j = 0; j < btns.length; j++) {
            btns[j].classList.remove('bgc')
          }

          // 复活他自己
          btns[i].classList.add('bgc')
        })
      }
    </script>
  </body>
</html>

image.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS 事件</title>
  </head>
  <style>
    button {
      border: 0;
    }
    .bgc {
      background-color: aqua;
    }
  </style>
  <body>
    <button class="bgc">按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>

    <script>
      let btns = document.querySelectorAll('button')

      for (let i = 0; i < btns.length; i++) {
        btns[i].addEventListener('click', () => {
          // 删除默认样式
          document.querySelector('.bgc').classList.remove('bgc')

          // 给自己添加
          btns[i].classList.add('bgc')
        })
      }
    </script>
  </body>
</html>

默认样式:

image.png

运行效果:

image.png

综合案例 - Tab 栏切换

需求描述:点击不同的选项卡,底部可以显示不同的内容

分析:

  • 点击当前选项卡,利用排他思想,移除所有类,然后给当前选项卡添加类;
  • 下面的模块盒子全部隐藏,只显示当前模块
<!DOCTYPE html>
<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title></title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }

      ul {
        list-style: none;
      }
      img {
        width: 1001px;
        height: 474px;
      }
      .wrapper {
        width: 1000px;
        height: 475px;
        margin: 0 auto;
        margin-top: 100px;
      }

      .tab {
        border: 1px solid #ddd;
        border-bottom: 0;
        height: 36px;
        width: 320px;
      }

      .tab li {
        position: relative;
        float: left;
        width: 80px;
        height: 34px;
        line-height: 34px;
        text-align: center;
        cursor: pointer;
        border-top: 4px solid #fff;
      }

      .tab span {
        position: absolute;
        right: 0;
        top: 10px;
        background: #ddd;
        width: 1px;
        height: 14px;
        overflow: hidden;
      }

      .products {
        width: 1002px;
        border: 1px solid #ddd;
        height: 476px;
      }

      .products .main {
        float: left;
        display: none;
      }

      .products .main.active {
        display: block;
      }

      .tab li.active {
        border-color: red;
        border-bottom: 0;
      }
    </style>
  </head>

  <body>
    <div class="wrapper">
      <ul class="tab">
        <li class="tab-item active">国际大牌<span></span></li>
        <li class="tab-item">国妆名牌<span></span></li>
        <li class="tab-item">清洁用品<span></span></li>
        <li class="tab-item">男士精品</li>
      </ul>
      <div class="products">
        <div class="main active">
          <a href="###"><img src="./guojidapai.jpg" alt="" /></a>
        </div>
        <div class="main">
          <a href="###"><img src="./guozhuangmingpai.jpg" alt="" /></a>
        </div>
        <div class="main">
          <a href="###"><img src="./qingjieyongpin.jpg" alt="" /></a>
        </div>
        <div class="main">
          <a href="###"><img src="./nanshijingping.jpg" alt="" /></a>
        </div>
      </div>
    </div>

    <script>
      let tab_items = document.querySelectorAll('.tab-item')
      let mains = document.querySelectorAll('.main')

      for (let i = 0; i < tab_items.length; i++) {
        tab_items[i].addEventListener('click', () => {
          for (let j = 0; j < tab_items.length; j++) {
            tab_items[j].classList.remove('active')
            mains[j].classList.remove('active')
          }
          tab_items[i].classList.add('active')
          mains[i].classList.add('active')
        })
      }
    </script>
  </body>
</html>

image.png

image.png