当前位置: 首页 > article >正文

轮播图案例

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

功能需求:

  • 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮
  • 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理
  • 图片播放的同时,下面的小圆圈模块跟随一起变化
  • 点击小圆圈,可以播放相应图片
  • 鼠标不经过轮播图,轮播图也会自动播放图片
  • 鼠标经过,轮播图模块,自动播放停止
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.addEventListener('load',function(){
  let that;
  class swiper{
    constructor(){
      that=this;
      this.imgList=document.querySelector('.imgList');
      this.dotList=document.querySelector('.dot');
      //获取图片的大小
      this.imgWidth=this.imgList.children[0].offsetWidth;
      //获取左右导航按钮
      this.leftBtn=document.querySelector('.prev');
      this.rightBtn=document.querySelector('.next');
      this.outer=document.querySelector('#outer');
      this.num=0;//图片索引
      this.currentdot=0;//当前圆点索引
      this.timer=null;
      this.autoPlay();
      this.crrateDot();
      this.cloneImg();
      this.addevent()
    }
    addevent(){
      this.dotList.addEventListener('click',this.clickDot)
      this.dotList.addEventListener('click',this.clickDotchangeImg)
      // 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮
      this.outer.addEventListener('mouseenter',this.showBtn)
      this.outer.addEventListener('mouseleave',this.hideBtn)
      //鼠标经过,轮播图模块,自动播放停止
      this.outer.addEventListener('mouseenter',this.outplay)
      this.outer.addEventListener('mouseleave',this.inplay)
      //点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理
      this.rightBtn.addEventListener('click',this.nextImg)
      this.leftBtn.addEventListener('click',this.prevImg)
    }
    //各种事件
    //创建小圆点
    crrateDot(){
      let  imgNum = this.imgList.children.length;
      console.log(imgNum);
      for(let i=0;i<imgNum;i++){
        let str="";
        str=`
          <a href="#" index="${i}"></a>
        `
        this.dotList.innerHTML+=str;
      }
     
      // 默认给第一个圆点添加active类
      this.dotList.children[0].className="active";
      console.log(this.dotList);
    }
    //点击小圆点颜色高亮并切换图片
    clickDot(e){
      // 阻止默认行为
      e.preventDefault();
      // 颜色高亮
      console.log(e.target.nodeName)
      if(e.target.nodeName=='A'){
        let dots=that.dotList.children;
        for(let i=0;i<dots.length;i++){
          dots[i].className="";

        } 
        e.target.className="active";
      }
      
     
    }
    //切换图片
    clickDotchangeImg(e){
      let index=e.target.getAttribute("index");
      console.log(index);
      animation(that.imgList,-index*that.imgWidth)
    }
    //鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮
    //出现左右按钮
    showBtn(){
      that.leftBtn.style.display="block";
      that.rightBtn.style.display="block";
    }
    // x隐藏左右按钮
    hideBtn(){
      that.leftBtn.style.display="none";
      that.rightBtn.style.display="none";
    }
    //点击右侧按钮一次,图片往左播放一张
    nextImg(){
      if(that.num<that.imgList.children.length-1){
        that.num++;
      }else{
        that.imgList.style.left=0;
        that.num=1;
      }
     animation(that.imgList,-that.num*that.imgWidth);
     let dotsLength=that.dotList.children.length;
     if(that.currentdot<dotsLength-1){
       that.currentdot++;
       
     }else{
       that.currentdot=0;
     }   
     that.changeColor()      
    }
    //点击左侧按钮一次,图片往右播放一张
    prevImg(){
      if(that.num>0){
        that.num--;
      }else{
        that.imgList.style.left=-(that.imgList.children.length-2)*that.imgWidth+'px';
        that.num=that.imgList.children.length-2;

      }
      animation(that.imgList,-that.num*that.imgWidth)
      
      let dotsLength=that.dotList.children.length;
      if(that.currentdot>0){
        that.currentdot--;
        
      }else{
        that.currentdot=that.dotList.children.length-1;;
      }
      
      that.changeColor()
    }
    //按钮点击小圆点颜色高亮,
    changeColor(){
      let dots=that.dotList.children;
      for(let i=0;i<dots.length;i++){
        dots[i].className="";
      }
      dots[that.currentdot].className="active";
    }
    //轮播图自动播放
    autoPlay(){
      that.timer=setInterval(function(){
        that.nextImg();
      },1000)
    }
    //鼠标经过,轮播图模块,自动播放停止
    outplay(){
      clearInterval(that.timer);
    }
    //input输入框内容变化,轮播图自动播放
    inplay(){
      that.autoPlay();
    }
    //实现无缝滚动效果
    cloneImg(){
      let fistimg=that.imgList.children[0].cloneNode(true);
      console.log(fistimg);
      that.imgList.appendChild(fistimg);
      
    }
  }
  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.kler.cn/a/571425.html

相关文章:

  • C++20中的std::bind_front使用及原理分析
  • 小米 SU7 Ultra:科技与性能的极致融合,FPC 隐匿的关键力量【新立电子】
  • Windows逆向工程入门之MASM STRUCT
  • Visual Studio Code 如何编写运行 C、C++ 程序
  • 多线程与异步任务处理(二):Kotlin协程
  • 【Linux篇】第一个系统程序 - 进度条
  • 【Laplacian边缘检测详解】
  • Compose Multiplatform开发记录之文件选择器封装
  • 三方库总结
  • 【Linux】【网络】UDP打洞-->不同子网下的客户端和服务器通信(成功版)
  • 鸿蒙与DeepSeek深度整合:构建下一代智能操作系统生态
  • 【leetcode hot 100 189】轮转数组
  • 从零开始学习Slam--数学概念
  • 《Operating System Concepts》阅读笔记:p180-p187
  • 蓝桥杯 2020 国赛 阶乘约数
  • 自学微信小程序的第十天
  • [liorf_localization_imuPreintegration-2] process has died
  • python全栈-Linux基础
  • 【Linux】进程信号——信号保存和信号捕捉
  • 【大模型】什么是蒸馏版大模型