javaScript交互案例

1、模态框(弹出框)

(1)、需求:

1、点击弹出层,会弹出模态框,并且显示灰色半透明的遮挡层

2、点击关闭按钮,可以关闭模态框,并且同时关闭半透明遮挡层

3、鼠标放在模态框最上面一行,可以按住鼠标拖拽模态框在页面中移动

4、鼠标松开,可以停止拖动模态框移动
思路:

1、点击弹出层,模态框和遮挡层就会显示出来 display:block

2、点击关闭按钮,模态框和遮罩层会隐藏起来 display:none

3、在页面中拖拽的原理:鼠标按下并且移动,之后松开鼠标

4、触发事件是鼠标按下mousedown,鼠标移动mousemove 鼠标松开 mouseup

5、拖拽过程,鼠标移动过程中,获得最新的值赋值给模态框的left和top值,这样模态框就可以跟着鼠标走了

6、鼠标按下触发的事件源是h2

7、鼠标的坐标减去鼠标内的坐标,才是模态框真正的位置

8、鼠标按下,我们要得到鼠标在盒子的坐标

9、鼠标移动,就让模态框的坐标设置为:鼠标坐标减去盒子坐标即可,注意移动时间写到按下

10、鼠标松开,就停止拖拽,可以让鼠标移动事件解除

(2)、es5

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      h1 {
        cursor: pointer;
        margin: 50px auto;
      }
      /* 模态框 */
      .modal-box {
        display: none;
        width: 400px;
        height: 300px;
        background-color: #bfa;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        z-index: 99;
      }
      button {
        position: absolute;
        right: 50px;
        top: 30px;
        width: 80px;
        line-height: 40px;
      }
      /* 遮罩层 */
      .bg {
        display: none;
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        background-color: #000;
        opacity: 0.3;
      }
      .title {
        background-color: aqua;
        line-height: 60px;
      }
    </style>
  </head>
  <body>
    <h1>点击,弹出模态框</h1>
    <!-- 弹出框 -->
    <div class="modal-box">
      <button>关闭</button>
      <h2 class="title">我是一个可爱的模态框·····</h2>
    </div>
    <!-- 遮罩层 -->
    <div class="bg"></div>
    <!-- js -->
    <script>
      // 1、获取元素
      var h1 = document.querySelector("h1");
      var modalBox = document.querySelector(".modal-box");
      var btn = document.querySelector("button");
      var bg = document.querySelector(".bg");
      var title = document.querySelector(".title");
      // 2、点击显示,隐藏模态框
      h1.onclick = function () {
        modalBox.style.display = "block";
        bg.style.display = "block";
      };
      btn.onclick = function () {
        modalBox.style.display = "none";
        bg.style.display = "none";
      };
      // 3、开始拖拽模态框
      //(1)、当我们鼠标按下,就获得鼠标在盒子内的坐标
      title.addEventListener("mousedown", function (e) {
        var x = e.pageX - modalBox.offsetLeft;
        var y = e.pageY - modalBox.offsetTop;
        //  (2)、鼠标移动的时候,把鼠标在页面中的坐标,减去鼠标在盒子内的坐标
         // 就是不断的求modalBox.offsetLeft ,modalBox.offsetTop
        // 不能直接用offset
        // 直接用offset得到的是盒子本来的坐标,盒子要动起来,才能改变offset的值,
        // 当我们是想要先改变offset然后用他来改变盒子的位置,所以不能直接用offset
        // 而是用鼠标的位置来动态的输入offset
        function move(e) {
          modalBox.style.left = e.pageX - x + "px";
          modalBox.style.top = e.pageY - y + "px";
           // 这样设置,会导致,初始化移动时,就把鼠标的位置,赋值给盒子的中心,有个跳跃的过程
          // modalBox.style.left = e.pageX  + "px";
          // modalBox.style.top = e.pageY  + "px";
          // modalBox.offsetLeft 是固定的值,不会变化的,需要先动盒子才能得到新的modalBox.offsetLeft
          // modalBox.style.left = modalBox.offsetLeft + "px";
          // modalBox.style.top = modalBox.offsetTop + "px";
        }
        document.addEventListener("mousemove", move);
        // (3)、鼠标弹起,就让鼠标移动事件移除
        document.addEventListener("mouseup", function () {
          document.removeEventListener("mousemove", move);
        });
      });
    </script>
  </body>
</html>

(3)、es6

javascript 复制代码
<script>
      let that;
      class Modal {
        constructor() {
          that = this;
          // 获取元素
          this.clickH1 = document.getElementById("clickH1");
          this.btn = document.getElementById("btn");
          this.modalBox = document.querySelector(".modal-box");
          this.bg = document.querySelector(".bg");
          this.title = document.querySelector(".title");
          // 调用监听函数
          this.event();
        }
        // 监听函数
        event() {
          this.clickH1.addEventListener("click", this.clickH1Fun);
          this.btn.addEventListener("click", this.btnFun);
          this.title.addEventListener("mousedown", this.titleFun);
        }
        // 点击出现遮罩层
        clickH1Fun() {
          that.bg.style.display = "block";
          that.modalBox.style.display = "block";
        }
        // 点击关闭按钮
        btnFun() {
          that.bg.style.display = "none";
          that.modalBox.style.display = "none";
        }
        //鼠标按下title
        titleFun(e) {
          // 获取鼠标在模态框中的位置方式一
          let x = e.offsetX;
          let y = e.offsetY;
          // 获取鼠标在模态框中的位置方式二
          // let x = e.pageX - that.modalBox.offsetLeft;
          // let y = e.pageY - that.modalBox.offsetTop;
          console.log(x, y);
          document.addEventListener("mousemove", moveFun);
          function moveFun(e) {
            // console.log(111);
            let left = e.pageX - x;
            let right = e.pageY - y;
            that.modalBox.style.left = left + "px";
            that.modalBox.style.top = right + "px";
            that.modalBox.style.margin = 0; //left 值变化,由于过度约束,需要重新设置margin
            // that.modalBox.style.transform='translate(0%, 0%)'//left 值变化,由于过度约束,需要重新设置偏移量
          }
          document.addEventListener("mouseup", upFun);
          function upFun() {
            document.removeEventListener("mousemove", moveFun);
          }
        }
      }
      new Modal();
    </script>

2、放大镜

(1)html/css

  1. 整个案例可以分为三个功能模块

  2. 鼠标经过小图片盒子,黄色的遮罩层和大图片盒子显示,离开隐藏2个盒子功能

  3. 黄色的遮挡层跟随鼠标移动功能

  4. 移动黄色遮挡层,大图片跟随移动功能

html

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>放大镜案例</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      /* 小图 */
      .camera {
        width: 300px;
        height: 300px;
        position: relative;
        border: 1px solid black;
      }

      .cameraImg img {
        width: 300px;
        height: 300px;
      }
      /* 遮罩层 */
      .zoom {
        width: 100px;
        height: 100px;
        background-color: #ccc;
        opacity: 0.8;
        position: absolute;
        top: 0px;
        left: 0px;
      }
      /* 大图 */

      .bDiv {
        width: 500px;
        height: 500px;
        background-color: bisque;
        position: absolute;
        left: 350px;
        top: 0;
        overflow: hidden;
      }
      .bImg {
        position: absolute;
        top: 0;
        left: 0;
      }
    </style>
  </head>

  <body>
    <div class="camera">
      <!-- 小图 -->
      <div class="cameraImg">
        <img src="./img0.jpg" alt="" />
      </div>
      <!-- 放大镜 -->
      <div class="zoom"></div>
      <!-- 大图 -->
      <div class="bDiv">
        <img src="./img1.jpg" alt="" class="bImg" />
      </div>
    </div>
    <!-- 引入js -->
    <script src="./放大镜.js"></script>
  </body>
</html>

(2)、es5 js

javascript 复制代码
window.onload = function () {
  var camera = document.querySelector(".camera");
  var zoom = document.querySelector(".zoom");
  var bDiv = document.querySelector(".bDiv");
  var bImg = document.querySelector(".bImg");
  // 1:给camera绑定鼠标移入移除事件,让鼠标移除时,放大镜跟展示页都消失
  camera.onmouseenter = function () {
    zoom.style.display = "block";
    bDiv.style.display = "block";
  };
  camera.onmouseleave = function () {
    // zoom.style.display = "none";
    // bDiv.style.display = "none";
  };
  // 2:设置放大镜zoom能跟着鼠标移动,并设置范围活动
  camera.onmousemove = function (event) {
    //2.1 获得鼠标的页面坐标x,y
    var x = event.pageX;
    var y = event.pageY;
    // console.log(x, y);
    //2.2 获取图相对于页面的左边,上边相对距离
    var offsetX = camera.offsetLeft;
    var offsetY = camera.offsetTop;
    // console.log(offsetX, offsetY);
    // 2.3 获取遮挡层的宽度跟高度
    var zoomW = zoom.offsetWidth;
    var zoomH = zoom.offsetHeight;
    // console.log(zoomW,zoomH);

    // 2.4 计算遮挡物的xy坐标
    var left = x - offsetX - zoomW / 2;
    var top = y - offsetY - zoomH / 2;

    // 2.5 设置判断left  top的限制值
    /* 遮盖物的最大移动距离,父元素camera的宽度减去遮盖物的宽度(300-100) */
    if (left >= 200) {
      left = 200;
    }
    if (left <= 0) {
      left = 0;
    }
    if (top >= 200) {
      top = 200;
    }
    if (top <= 0) {
      top = 0;
    }
    //2.6 将宽高赋值给放大镜
    zoom.style.left = left + "px";
    zoom.style.top = top + "px";

    /* 3、根据比例移动大图  
    遮罩层的移动距离 /遮罩层最大移动距离 = 大图片移动距离/大图片最大移动距离
    根据上面的等式,可以演算出
    大图片的移动距离=(遮罩层的移动距离 /遮罩层最大移动距离)*大图片最大移动距离 */

    //3.1 计算大图在大盒子里移动的最大距离

    /* 大图的宽度,减去bDiv框子的宽度*/
    var bImgMw = bImg.offsetWidth - bDiv.offsetWidth;
    var bImgMh = bImg.offsetHeight - bDiv.offsetHeight;
    // console.log(bDiv.offsetWidth);

    // 3.2 根据比例移动大图
    var bX = (left / 200) * bImgMw;
    var bY = (top / 200) * bImgMh;

    // 3.3 将bX,bY赋值给大图的宽高
    bImg.style.left = -bX + "px";
    bImg.style.top = -bY + "px";
  };
};

(3)、es6.js

javascript 复制代码
window.onload = function () {
  var that;
  class Camera {
    constructor() {
      // 保存this
      that = this;
      // 获取整个盒子
      this.camera = document.querySelector(".camera");
      this.zoom = document.querySelector(".zoom");
      this.bDiv = document.querySelector(".bDiv");
      this.bImg = document.querySelector(".bImg");
      //初始化放大镜的位置left,top
      this.left = 0;
      this.top = 0;
      //初始化监听函数
      this.addevent();
    }
    // 监听事件
    addevent() {
      //1.1、移入显示放大镜,移出隐藏放大镜
      this.camera.addEventListener("mouseenter", that.showZoom);
      this.camera.addEventListener("mouseleave", that.hiddZoom);
      //2、移入,放大镜随着鼠标移动
      this.camera.addEventListener("mousemove", that.zoomMove);
      //2、放大镜移动,大图也随着移动
      this.camera.addEventListener("mousemove", that.bDivMove);
    }
    //1.2 鼠标移入,显示放大镜及大图
    showZoom() {
      that.zoom.style.display = "block";
      that.bDiv.style.display = "block";
    }
    hiddZoom() {
      that.zoom.style.display = "none";
      that.bDiv.style.display = "none";
    }
    // 1.2 放大镜随着鼠标移动
    zoomMove(e) {
      // 如果直接赋值,会出现闪烁,由于只有鼠标动了,才会获取到offseX/Y的值,移动之前为0
      // let left = e.offsetX;
      // let top = e.offsetY;
      // (1)、鼠标在页面中的坐标
      var x = e.pageX;
      var y = e.pageY;
      //(2)、大盒子camera在在页面中的位置
      var offsetLeft = that.camera.offsetLeft;
      var offsetTop = that.camera.offsetTop;
      //(3)、计算zoom的大小
      var zoomWidth = that.zoom.offsetWidth;
      var zoomHeight = that.zoom.offsetHeight;

      //(4)、计算盒子中鼠标的位置
      that.left = x - offsetLeft - zoomWidth / 2;
      that.top = y - offsetTop - zoomHeight / 2;

      //(5)、限制放大镜的移动范围,camera-zoom
      if (that.left <= 0) {
        that.left = 0;
      }
      if (that.left >= 200) {
        that.left = 200;
      }
      if (that.top <= 0) {
        that.top = 0;
      }
      if (that.top >= 200) {
        that.top = 200;
      }

      //(6)、将计算出的鼠标位置赋值给zoom
      that.zoom.style.left = that.left + "px";
      that.zoom.style.top = that.top + "px";
    }
    // 3、放大镜移动,大图也随着移动
    // zoom移动距离/zoom最大移动距离 = 大图移动距离/大图最大移动距离

    bDivMove() {
      // 计算大图的最大移动距离  大图-大图盒子大小
      var bimgMaxWidth = that.bImg.offsetWidth - that.bDiv.offsetWidth;
      var bimgMaxHeight = that.bImg.offsetHeight - that.bDiv.offsetHeight;
      // 计算大图移动距离(zoom移动距离/zoom最大移动距离)*大图最大移动距离
      var bimgLeft = (that.left / 200) * bimgMaxWidth;
      var bimgTop = (that.top / 200) * bimgMaxHeight;

      that.bImg.style.left = -bimgLeft + "px";
      that.bImg.style.top = -bimgTop + "px";
    }
  }
  new Camera();
};

3、京东侧边导航条

需求:

  1. 原先侧边栏是绝对定位

  2. 当页面滚动到一定位置,侧边栏改为固定定位

  3. 页面继续滚动,会让返回顶部显示出来

思路:

  1. 需要用到页面滚动事件scroll,因为是页面滚动,所以事件源是document

  2. 滚动到某个位置,就是判断页面被卷去的上部值

  3. 页面被卷去的头部:可以通过window.pageYOffset获得,如果是被卷去的左侧window.pageXOffset

  4. 注意:元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>侧边栏案例</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      header,
      footer {
        width: 1000px;
        height: 200px;
        background-color: pink;
        margin: 0 auto;
      }
      main {
        width: 1000px;
        height: 800px;
        background-color: #bfa;
        margin: 0 auto;
      }
      nav {
        width: 60px;
        height: 200px;
        background-color: blue;
        position: absolute;
        right: 0;
        top: 250px;
        line-height: 30px;
      }
      span {
        display: block;
        width: 60px;
        height: 60px;
        background-color: red;
        margin-top: 140px;
        text-align: center;
        display: none;
      }
    </style>
  </head>
  <body>
    <header>头部</header>
    <nav>
      <span
        >返回 <br />
        顶部</span
      >
    </nav>
    <main>主体</main>
    <footer>底部</footer>
    <script>
      // 1、获取元素
      var span = document.querySelector("span");
      var nav = document.querySelector("nav");
      var main = document.querySelector("main");
      // 主体以上被卷去的距离
      var mainTop = main.offsetTop;
      // 侧边导航以上被卷去的距离
      var navTop = nav.offsetTop;
      console.log(navTop);
      // 2、页面滚动事件 scroll
      document.addEventListener("scroll", function () {
        // window.pageYOffset 获取页面被滚去的距离
        // 3、判断距离,变化定位
        if (window.pageYOffset >= mainTop) {
          // 3.1将定位改成固定定位
          nav.style.position = "fixed";
          // 3.2 改成固定定位后,会有跳动,需要重新设置定位的top值,否则还是原值
          nav.style.top = navTop - mainTop + "px";
          // 3.3 出现返回顶部字样
          span.style.display = "block";
        } else {
          nav.style.position = "absolute";
          nav.style.top = "300px";
          span.style.display = "none";
        }
      });
    </script>
  </body>
</html>

4、轮播图

(1)、搭建轮播图的结构

javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>轮播图结构</title>
    <!-- <script src="../js/tools.js"></script> -->
    <script src="../js/animation.js"></script>
    <script src="./01.轮播图.js"></script>
    <style>
      * {
        padding: 0;
        margin: 0;
        list-style: none;
        text-decoration: none;
      }
      #outer {
        width: 590px;
        height: 470px;
        border: 10px solid red;
        margin: 50px auto;
        position: relative;
        overflow: hidden;
      }
      #outer > ul {
        width: 500%;
        position: absolute;
        left: 0;
        top: 0;
      }
      #outer > ul > li {
        float: left;
      }
      .dot {
        position: absolute;
        bottom: 30px;
        left: 50%;
        transform: translate(-50%, -50%);
      }
      .dot > a {
        display: inline-block;
        width: 15px;
        height: 15px;
        border-radius: 50%;
        background-color: #999;
        margin: 0 5px;
      }
      .dot > .active,
      .dot > a:hover {
        background-color: orange;
      }
      .prev,
      .next {
        width: 40px;
        height: 40px;
        background-color: rgba(0, 0, 0, 0.4);
        text-align: center;
        position: absolute;
        font-size: 30px;
        color: #999;
        /* 隐藏左右按钮 */
        display: none;
      }
      .prev > a,
      .next > a {
        color: #fff;
      }
      .prev {
        left: 10px;
        top: 42%;
      }
      .next {
        right: 10px;
        top: 42%;
      }
    </style>
  </head>
  <body>
    <div id="outer">
      <!-- 图片部分 -->
      <ul>
        <li>
          <a href="#"><img src="./img/1.jpg" alt="" /></a>
        </li>
        <li>
          <a href="#"><img src="./img/2.jpg" alt="" /></a>
        </li>
        <li>
          <a href="#"><img src="./img/3.jpg" alt="" /></a>
        </li>
        <li>
          <a href="#"><img src="./img/4.jpg" alt="" /></a>
        </li>
        <!-- <li>
          <a href="#"><img src="./img/1.jpg" alt="" /></a>
        </li> -->
      </ul>
      <!-- 导航点  class="active"-->
      <div class="dot">
        <!-- <a href="#" ></a>
        <a href="#"></a>
        <a href="#"></a>
        <a href="#"></a> -->
      </div>
      <!-- 左右导航 -->
      <ol class="prevNext">
        <li class="prev">
          <a href="#"> &lt;</a>
        </li>
        <li class="next">
          <a href="#">&gt;</a>
        </li>
      </ol>
    </div>
  </body>
</html>

(2)、es5写法

功能需求:

  • 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮

  • 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理

  • 图片播放的同时,下面的小圆圈模块跟随一起变化

  • 点击小圆圈,可以播放相应图片

  • 鼠标不经过轮播图,轮播图也会自动播放图片

  • 鼠标经过,轮播图模块,自动播放停止

es5写法

javascript 复制代码
window.addEventListener("load", function () {
  var prev = this.document.querySelector(".prev");
  var next = this.document.querySelector(".next");
  var outer = this.document.querySelector("#outer");
  //需求1 鼠标移入,左右按钮出现隐藏
  outer.addEventListener("mouseenter", function () {
    prev.style.display = "block";
    next.style.display = "block";
  });
  outer.addEventListener("mouseleave", function () {
    prev.style.display = "none";
    next.style.display = "none";
  });

  //需求2 动态生成pot,小圆圈
  // 2.1、获取元素
  var ulL = outer.querySelector("ul");
  var dot = outer.querySelector(".dot");
  for (var i = 0; i < ulL.children.length; i++) {
    // 2.2、动态的创建a标签
    var a = this.document.createElement("a");
    // 给a添加索引,方便下面计算点击圆圈,移动图片
    a.setAttribute("index", i);
    // 2.3 插入节点
    dot.appendChild(a);
  }
  // 2.4 给第一个小点,设置选中样式
  dot.children[0].className = "active";

  //需求3  给点击的小圆圈加上类名 active  排他思想
  var as = dot.querySelectorAll("a");
  for (var i = 0; i < as.length; i++) {
    as[i].addEventListener("click", function () {
      for (var j = 0; j < as.length; j++) {
        dot.children[j].className = "";
      }
      this.className = "active";

      //需求4   点击小圆圈,移动图片 move(obj, attr, target, speed, callback)
      //4.1  获取点击a的索引,这个索引是创建a时添加的,用来表示每个a
      var index = this.getAttribute("index");
      // 4.2 ulL的移动距离,小圆圈的索引号*图片的宽度
      animation(ulL, -index * 590);
      // move(ulL, "left", -index * 590, 10);
      // 获取到index后,需要同步赋值给下面的num跟current

      // 以便可以同步小圆点,跟点击下一张的变化
      num = index;
      current = index;
    });
  }
  // 克隆第一张图片,不在结构里加
  // 循环生成小圆点的时候,还没有克隆这个图片。所有不会自动生成的小圆圈
  var firstImg = ulL.children[0].cloneNode(true);
  ulL.appendChild(firstImg);

  //需求5  点击左右按钮,实现上下一张切换
  var num = 0;
  var current = 0; //用来标记小圆圈
  next.addEventListener("click", function () {
    //无缝滚动  如果走到了最后一张图片,此时我们的ul要快速复原left改为0
    if (num >= ulL.children.length - 1) {
      ulL.style.left = 0;
      num = 0;
    }
    num++;
    animation(ulL, -num * 590);
    // move(ulL, "left", -num * 590, 20);

    // 点击右侧按钮,小圆圈跟着跳动
    current++;
    // 如果curent的数值跟小圆圈的数量一样,走到了克隆的那张图片,要还原为0
    if (current == dot.children.length) {
      current = 0;
    }
    for (var i = 0; i < dot.children.length; i++) {
      dot.children[i].className = "";
    }
    dot.children[current].className = "active";
  });

  //需求6  左侧按钮的功能
  prev.addEventListener("click", function () {
    if (num == 0) {
      num = ulL.children.length - 1;
      ulL.style.left = -num * 590 + "px";
    }
    num--;
    animation(ulL, -num * 590);
    // move(ulL, "left", -num * 590, 20);
    // 点击右侧按钮,小圆圈跟着跳动
    current--;
    // 如果curent的数值跟小圆圈的数量一样,要还原为0
    if (current < 0) {
      current = dot.children.length - 1;
    }
    for (var i = 0; i < dot.children.length; i++) {
      dot.children[i].className = "";
    }
    dot.children[current].className = "active";
  });

  //需求7  自动播放功能
  var timer = setInterval(function () {
    // 手动调用点击事件
    next.click();
  }, 2000);
  
  //需求8  鼠标移入,自动播放停止
  outer.addEventListener("mouseenter", function () {
    clearInterval(timer);
    timer = null;
  });

  //需求9  鼠标移出,重新开启定时器
  outer.addEventListener("mouseleave", function () {
    timer = setInterval(function () {
      // 手动调用点击事件
      next.click();
    }, 2000);
  });
});

(3)、es6写法

javascript 复制代码
window.onload = function () {
  var that;
  class Swiper {
    constructor() {
      // 保存this
      that = this;
      // 1.1 获取对应元素
      this.prev = document.querySelector(".prev");
      this.next = document.querySelector(".next");
      this.outer = document.querySelector("#outer");
      //2.1 获取导航点父元素
      this.dot = document.querySelector(".dot");
      this.imgList = document.querySelector(".imgList");
      //   2.4 调用创建小圆点函数
      this.creatDot();
      //   3.1 获取图片导航小圆点
      this.dots = document.querySelectorAll(".dot a");
      //   4.1 用于标识当前的图片位置
      this.num = 0;
      this.current = 0; //用于标识当前小圆点的位置
      //   5、克隆轮播图第一张照片
      this.cloneFirstImg();

      // 调用监听函数
      this.addevent();
    }
    // 所有监听函数
    addevent() {
      console.log(this);
      // 1.2 监听鼠标是否移入
      this.outer.addEventListener("mouseenter", that.pervNextShow);
      this.outer.addEventListener("mouseleave", that.pervNextNode);
      //  3.3 监听是否点击了小圆点
      for (var i = 0; i < this.dots.length; i++) {
        // 保存i值,方便找对应的图片
        this.dots[i].index = i;
        // 默认第一个按钮为选中状态
        this.dots[0].className = "active";
        // 点击切换背景色
        this.dots[i].addEventListener("click", that.updatBackgroundColor);
        // 点击切换图片
        this.dots[i].addEventListener("click", that.updatImg);
      }
      //   4、点击next
      this.next.addEventListener("click", that.nextFun);
      //   5、点击prev
      this.prev.addEventListener("click", that.prevFun);
      //   8、调用自动轮播函数
      this.timer = null; //定义标识定时器
      this.autoPlay();
      // 9、移入outer,暂停自动轮播
      this.outer.addEventListener("mouseenter", that.stopAutoPlay);
      //   10、移出outer,继续自动轮播
      this.outer.addEventListener("mouseleave", that.startAutoPlay);
    }
    // 所有功能函数
    // 注意函数中的this指向
    // 1.3 上下一张出现
    pervNextShow() {
      that.prev.style.display = "block";
      that.next.style.display = "block";
    }
    pervNextNode() {
      that.prev.style.display = "none";
      that.next.style.display = "none";
    }
    // 2、根据图片创建导航点
    creatDot() {
      var imgNum = this.imgList.children.length;
      for (var i = 0; i < imgNum; i++) {
        var a = `<a href="#" ></a>`;
        this.dot.insertAdjacentHTML("afterBegin", a);
      }
    }
    // 3.4 点击小圆点,切换颜色
    updatBackgroundColor(e) {
      // (1)、先解决默认行为,超链接跳转的问题
      e.preventDefault();
      //  (2)、点击颜色切换
      for (var i = 0; i < that.dots.length; i++) {
        that.dots[i].className = "";
      }
      this.className = "active";
    }

    // 3.5 点击小圆点,切换图片
    updatImg() {
      //  (3)、根据图片导航点的索引移动图片
      animation(that.imgList, -590 * this.index);
    }

    // 4、点击下一张,切换图片
    nextFun() {
      // 根据num的值,判断num是否++
      var len = that.imgList.children.length;
      if (that.num >= len - 1) {
        that.imgList.style.left = 0;
        that.num = 0;
      }
      that.num++;

      animation(that.imgList, -that.num * 590);

      // 点击下一张照片后,更换小圆点背景色
      that.current++;
      if (that.current == that.dots.length) that.current = 0;
      //调用更换小圆点颜色函数
      that.changeBackgroundColor();
    }
    // 5、为解决轮播图最后一张快速问题,多赋值一张照片
    cloneFirstImg() {
      var firstImg = that.imgList.children[0].cloneNode(true);
      that.imgList.appendChild(firstImg);
    }
    // 6、更换小圆点颜色
    changeBackgroundColor() {
      for (var i = 0; i < that.dots.length; i++) {
        that.dots[i].className = "";
      }
      that.dots[that.current].className = "active";
    }
    // 7、点击prev,上一张照片
    prevFun() {
      // 根据num的值,判断显示图片
      if (that.num == 0) {
        that.num = that.imgList.children.length - 1;
        that.imgList.style.left = -that.num * 590 + "px";
      }
      that.num--;
      animation(that.imgList, -that.num * 590);
      //  同步图片小圆点的背景色
      if (that.current <= 0) {
        that.current = that.dots.length;
      }
      that.current--;
      //调用更换小圆点颜色函数
      that.changeBackgroundColor();
    }
    // 8、自动轮播,每隔2s,调动一次next函数
    autoPlay() {
      that.timer = setInterval(function () {
        that.nextFun();
      }, 2000);
    }
    // 9、鼠标移入轮播图,停止自动轮播
    stopAutoPlay() {
      //   console.log(that.timer);
      clearInterval(that.timer);
      that.timer = null;
    }
    // 10、鼠标移出轮播图,开始自动轮播
    startAutoPlay() {
      that.autoPlay();
    }
  }
  new Swiper();
};

(4)、节流阀优化

防止轮播图按钮连续点击造成播放过快

节流阀目的,当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数

开始设置一个变量 var flag =true

if(flag){ flag = false,do something} 关闭水龙头

利用回调函数动画执行完毕, falg=true 打开水龙头

javascript 复制代码
 // 10、节流阀优化点击过快问题
  var flag = true;
  next.addEventListener("click", function () {
    if (flag) {
      flag = false; // 关闭水龙头
      //无缝滚动  如果走到了最后一张图片,此时我们的ul要快速复原left改为0
      if (num >= ulL.children.length - 1) {
        ulL.style.left = 0;
        num = 0;
      }
      num++;
      animation(ulL, -num * 590, function () {
        flag = true;
      });
      // move(ulL, "left", -num * 590, 20);

      // 点击右侧按钮,小圆圈跟着跳动
      current++;
      // 如果curent的数值跟小圆圈的数量一样,走到了克隆的那张图片,要还原为0
      if (current == dot.children.length) {
        current = 0;
      }
      for (var i = 0; i < dot.children.length; i++) {
        dot.children[i].className = "";
      }
      dot.children[current].className = "active";
    }
  });

  //需求6  左侧按钮的功能
  prev.addEventListener("click", function () {
    if (flag) {
      flag = false;
      if (num == 0) {
        num = ulL.children.length - 1;
        ulL.style.left = -num * 590 + "px";
      }
      num--;
      animation(ulL, -num * 590, function () {
        flag = true;
      });
      // move(ulL, "left", -num * 590, 20);
      // 点击右侧按钮,小圆圈跟着跳动
      current--;
      // 如果curent的数值跟小圆圈的数量一样,要还原为0
      if (current < 0) {
        current = dot.children.length - 1;
      }
      for (var i = 0; i < dot.children.length; i++) {
        dot.children[i].className = "";
      }
      dot.children[current].className = "active";
    }
  });
相关推荐
梓贤Vigo5 小时前
【Axure教程】动态统计字数
交互·产品经理·axure·原型
聆思科技AI芯片9 小时前
实操给触摸一体机接入大模型语音交互
交互
liuweni2 天前
Next.js系统性教学:深入理解缓存交互与API缓存管理
开发语言·前端·javascript·经验分享·缓存·前端框架·交互
设计芝士波波球2 天前
原型设计规范:Axure RP中的交互和布局
交互·axure·设计规范
梓贤Vigo4 天前
【Axure高保真原型】批量美化滚动条
交互·产品经理·axure·原型
little_fat_sheep4 天前
【Rive】Android与Rive交互
android·交互·text·rive·inputs
广州虚拟动力-动捕&虚拟主播4 天前
mHand Pro动捕数据手套,赋予手部虚拟交互沉浸式极致体验
科技·交互·vr
xiaokcehui4 天前
VB.net进行CAD二次开发(二)与cad交互
交互·cad