JavaScript纯手工实现轮播图(无缝切换)效果

一、需求

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

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

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

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

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

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

        - 实现无缝切换效果

二、搭建结构

1、HTML部分

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>轮播图结构</title>
    <link rel="stylesheet" href="./css/index.css">
    <script src="./js/animation.js"></script>
    <script src="./js/轮播图(ES6).js"></script>
  </head>
  <body>
    <div id="outer">
      <!-- 图片部分 -->
      <ul class="imgList">
        <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>
      </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="javascript:;"> &lt;</a>
        </li>
        <li class="next">
          <a href="javascript:;">&gt;</a>
        </li>
      </ol>
    </div>
  </body>
</html>

三、CSS代码

* {
 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: 600%;
  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;
}
.active,
.dot > a:hover {
  background-color: orange !important;
}
.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%;
}

四、JS部分代码

这部分代码可以采用ES5写法,也可以采用ES6写法,这两者可以相互切换,本文就采用ES6写法

<script>
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()
})
</script>

五、js动画

这里为了切换效果更丝滑,封装了一个JS动画函数,只需要引入,在需要的地方直接调用就可以,比如上面JS代码里的 animation(that.imgList, -that.num * that.imgWidth);就是直接调用了动画函数,把下方的代码直接另存为一个js文件引入即可。

function animation(obj, target, callback) {
  clearInterval(obj.time);
  obj.time = setInterval(function () {
    var step = (target - obj.offsetLeft) / 10;
    step = step > 0 ? Math.ceil(step) : Math.floor(step);
    if (obj.offsetLeft == target) {
      clearInterval(obj.time);
      if (callback) {
        callback();
      }
    } else {
      obj.style.left = obj.offsetLeft + step + "px";
    }
  }, 15);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值