javaScript交互案例

news2024/12/19 21:43:39

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

<!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

<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

<!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

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

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

<!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)、搭建轮播图的结构

<!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写法

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写法

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 打开水龙头

 // 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";
    }
  });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262374.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux文件属性 --- 硬链接、所有者、所属组

三、硬链接数 1.目录 使用“ll”命令查看&#xff0c;在文件权限的后面有一列数字&#xff0c;这是文件的硬链接数。 对于目录&#xff0c;硬链接的数量是它具有的直接子目录的数量加上其父目录和自身。 下图的“qwe”目录就是“abc”目录的直接子目录。 2.文件 对于文件可…

Centos7 部署ZLMediakit

1、拉取代码 #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit #千万不要忘记执行这句命令 git submodule update --init 2、安装编译器 sudo yum -y install gcc 3、安装cmake sudo yum -y install cmake 4…

无管理员权限 LCU auth-token、port 获取(全网首发 go)

一&#xff1a; 提要&#xff1a; 参考项目&#xff1a; https://github.com/Zzaphkiel/Seraphine 想做一个 lol 查战绩的软件&#xff0c;并且满足自己的需求&#xff08;把混子和大爹都表示出来&#xff09;&#xff0c;做的第一步就是获取 lcu token &#xff0c;网上清一色…

《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制

从本节课程开始&#xff0c;我们将来介绍K8s安全框架&#xff0c;这是保障K8s集群安全比较关键的安全机制。接下来&#xff0c;让我们一起来探索K8s安全框架的运行机制。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; K8s安全框架&#xff1a;由认证、鉴权和准入控…

spring\strust\springboot\isp前后端那些事儿

后端 一. 插入\更新一条数据&#xff08;老&#xff09; Map<String, Object> parameterMap MybatisUtil.initParameterSave("Send_ProjectFrozenLog", sendProjectFrozenLog); commonMapper.insert(parameterMap);parameterMap MybatisUtil.initParameter…

UE5安装Fab插件

今天才知道原来Fab也有类似Quixel Bridge的插件&#xff0c;于是立马就安装上了&#xff0c;这里分享一下安装方法 在Epic客户端 - 库 - Fab Library 搜索 Fab 即可安装Fab插件 然后重启引擎&#xff0c;在插件面板勾选即可 然后在窗口这就有了 引擎左下角也会多出一个Fab图标…

对于使用exe4j打包,出现“NoClassDefFoundError: BOOT-INF/classes”的解决方案

jar使用exe4j打包exe&#xff0c;出现NoClassDefFoundError: BOOT-INF/classes 注意选取的jar包是使用build&#xff0c;而不是maven中的install 本文介绍解决这个方法的方案 点击Project Structure 按照如图所示选择 选择main class&#xff0c;选择你要打的main 如果遇到/M…

文件上传之文件内容检测

一.基本概念 介绍&#xff1a;文件内容检测就是检测上传的文件里的内容。 文件幻数检测 通常情况下&#xff0c;通过判断前10个字节&#xff0c;基本就能判断出一个文件的真实类型。 文件加载检测 一般是调用API或函数对文件进行加载测试。常见的是图像渲染测试&#xff0c;再…

WebSpoon9.0(KETTLE的WEB版本)编译 + tomcatdocker部署 + 远程调试教程

前言 Kettle简介 Kettle是一款国外开源的ETL工具&#xff0c;纯Java编写&#xff0c;可以在Window、Linux、Unix上运行&#xff0c;绿色无需安装&#xff0c;数据抽取高效稳定 WebSpoon是Kettle的Web版本&#xff0c;由Kettle社区维护&#xff0c;不受Pentaho支持&#xff0c;…

搭建Tomcat(三)---重写service方法

目录 引入 一、在Java中创建一个新的空项目&#xff08;初步搭建&#xff09; 问题&#xff1a; 要求在tomcat软件包下的MyTomcat类中编写main文件&#xff0c;实现在MyTomcat中扫描myweb软件包中的所有Java文件&#xff0c;并返回“WebServlet(url"myFirst")”中…

CAN配置---波特率中断引脚等---autochips-AC7811-ARM-M3内核

1、配置工具 虽然不怎么好用&#xff0c;但比没有强多了。具体看图&#xff1a; 时钟选着 NVIC配置 GPIO配置 2、生成的具体配置信息 NXP的配置工具里面&#xff0c;具体的波特率可以直接显示&#xff0c;这个工具没有&#xff0c;怎么办&#xff1f; 它放到了生成的代码里面…

matlab Patten的使用(重要)(Matlab处理字符串一)

原文连接&#xff1a;https://www.mathworks.com/help/releases/R2022b/matlab/ref/pattern.html?browserF1help 能使用的搜索函数&#xff1a; contains确定字符串中是否有模式matches确定模式是否与字符串匹配count计算字符串中模式的出现次数endsWith确定字符串是否以模式…

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍02-基于错误消息的SQL注入(Error-Based SQL Injection)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

OpenCVE:一款自动收集NVD、MITRE等多源知名漏洞库的开源工具,累计收录CVE 27万+

漏洞库在企业中扮演着至关重要的角色&#xff0c;不仅提升了企业的安全防护能力&#xff0c;还支持了安全决策、合规性要求的满足以及智能化管理的发展。前期博文《业界十大知名权威安全漏洞库介绍》介绍了主流漏洞库&#xff0c;今天给大家介绍一款集成了多款漏洞库的开源漏洞…

Spring Boot 3.X:Unable to connect to Redis错误记录

一.背景 最近在搭建一个新项目&#xff0c;本着有新用新的原则&#xff0c;项目选择到了jdk17SpringBoot3.4。但是在测试Redis连接的时候却遇到了以下问题&#xff1a; redis连不上了。于是我先去检查了配置文件的连接信息&#xff0c;发现没问题&#xff1b;再去检查配置类&am…

MinT: 第一个能够生成顺序事件并控制其时间戳的文本转视频模型。

MinT 是第一个能够生成顺序事件并控制其时间戳的文本转视频模型。使用 MinT 生成时间控制的多事件视频。给定一系列事件文本提示及其所需的开始和结束时间戳&#xff0c;MinT 可以合成具有一致主题和背景的平滑连接事件。此外&#xff0c;它可以灵活地控制每个事件的时间跨度。…

C语言实验 结构体2

时间:2024.12.18 6-5 评委打分-t-CalcuScore 代码 // 定义结构体 struct Score {int id;char name[10];int value[17];double finalScore;int rank; };// 计算最终成绩 void CalcuScore(struct Score grade[], int n) {for (int i = 0; i < n; i++) {int max = grade[i].…

第6章 第一组重构

最常用到的重构就是用提炼函数&#xff08;106&#xff09;将代码提炼到函数中&#xff0c;或者用提炼变量&#xff08;119&#xff09;来提炼变量。既然重构的作用就是应对变化&#xff0c;你应该不会感到惊讶&#xff0c;我也经常使用这两个重构的反向重构——内联函数&#…

基于python对网页进行爬虫简单教程

python对网页进行爬虫 基于BeautifulSoup的爬虫—源码 """ 基于BeautifulSoup的爬虫### 一、BeautifulSoup简介1. Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱&#xff0c;通过解析文档为用户提供需要…