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";
    }
  });
相关推荐
一條狗18 分钟前
隨筆 20241224 ts寫入excel表
开发语言·前端·typescript
小码快撩23 分钟前
vue应用移动端访问缓慢问题
前端·javascript·vue.js
低调之人27 分钟前
Fiddler勾选https后google浏览器网页访问不可用
前端·测试工具·https·fiddler·hsts
yayaya15232 分钟前
javaScriptBOM
开发语言·javascript·ecmascript
Riesenzahn33 分钟前
使用vue如何监听元素尺寸的变化?
前端·javascript
阿征学IT37 分钟前
圣诞快乐(h5 css js(圣诞树))
前端·javascript·css
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭39 分钟前
C#都可以找哪些工作?
开发语言·c#
程序员黄同学40 分钟前
如何使用 Flask 框架创建简单的 Web 应用?
前端·python·flask
Sword9941 分钟前
豆包 MarsCode AI Apply功能揭秘:自动代码应用与 Diff 实现
前端·人工智能·豆包marscode
前端与小赵41 分钟前
什么是全栈应用,有哪些特点
前端