轮播图

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>circular1</title>
  <style>
    .container {
      width: 522px;
      height: 222px;
      box-sizing: border-box;
      padding: 10px;
      border: 1px solid gray;
      position: relative;
      margin: auto;
      top: 30px;
      overflow: hidden;
    }
    ul, ol {
      list-style: none;
      padding: 0px;
      margin: 0px;
    }

    ul li {
      float: left;
    }

    .box {
      width: 500px;
      height: 200px;
      position: relative;
      overflow: hidden;
    }

    .pics {
      width: 1000%;
      position: absolute;
      left: -500px;
    }

    .box img {
      width: 500px;
      height: 200px;
    }

    .container ol {
      position: absolute;
      bottom: 20px;
      text-align: center;
      width: 500px;
    }

    .container ol li {
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background-color: white;
      color: #333;
      line-height: 20px;
      text-align: center;
      margin-right: 10px;
      cursor: pointer;
      user-select: none;
    }

    .container ol li:last-child {
      margin-right: 0;
    }

    .container ol li.cur {
      background: purple;
      color: white;
    }

    .container .left, .container .right {
      position: absolute;
      width: 40px;
      height: 60px;
      line-height: 60px;
      text-align: center;
      color: white;
      background-color: rgba(0, 0, 0, .3);
      cursor: pointer;
      top: 100px;
      margin-top: -30px;
      display: none;
      user-select: none;
    }

    .container:hover .left, .container:hover .right {
      display: block;
    }

    .container .left {
      left: 10px;
    }

    .container .right {
      right: 10px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box">
      <ul class="pics">
        <li><img src="../images/1.jpg"></li>
        <li><img src="../images/2.jpg"></li>
        <li><img src="../images/3.jpg"></li>
        <li><img src="../images/4.jpg"></li>
        <li><img src="../images/5.jpg"></li>
      </ul>
    </div>
    <div class="left"><</div>
    <div class="right">></div>
  </div>

  <script>
    //动画函数
    function animate(obj, target){
      clearInterval(obj.timer);
      let frameTime = Math.abs((target - obj.offsetLeft) / 62);
      let speed = target < obj.offsetLeft ? -frameTime : frameTime;
      obj.timer = setInterval( () => {
        let leftDistance = Math.abs(target - obj.offsetLeft);
        if( leftDistance < Math.abs(speed) ){
          obj.style.left = target + 'px';
        }else{
          obj.style.left = obj.offsetLeft + speed + 'px';
        }
      }, 16);
    }

    //获取相关元素,在前后添加图片,生成小点
    let container = document.getElementsByClassName('container')[0];
    let pics = document.getElementsByClassName('pics')[0];
    let picWidth = pics.children[0].offsetWidth;
    let left = document.getElementsByClassName('left')[0];
    let right = document.getElementsByClassName('right')[0];
    pics.appendChild(pics.children[0].cloneNode(true));
    pics.insertBefore(pics.children[pics.children.length-2].cloneNode(true),pics.children[0]);

    let ol = document.createElement('ol');
    for( let i = 0, len = pics.children.length-2; i < len; i++){
      let li = document.createElement('li');
      li.innerHTML = i + 1;
      ol.appendChild(li);
    }
    container.appendChild(ol);

    //控制变量
    let timer = null;
    let curImg = 1;
    let dot = 0;

    //改变小点样式
    function dotStyle(){
      for(let i = 0, len = ol.children.length; i< len; i++){
        if( dot === i){
          ol.children[i].className = 'cur';
        }else {
          ol.children[i].className = '';
        }
      }
    }

    //点击小点
    for(let i = 0, len = ol.children.length; i < len; i++){
      ol.children[i].index = i;
      ol.children[i].addEventListener('click',function(){
        //修正位置
        if(curImg === pics.children.length - 1){
          pics.style.left = pics.offsetLeft + picWidth * (pics.children.length - 2) + 'px';
        }
        if(curImg === 0){
          pics.style.left = pics.offsetLeft - picWidth * (pics.children.length - 2) + 'px';
        }
        

        dot = this.index;
        curImg = this.index + 1;
        dotStyle();
        animate(pics,- picWidth * curImg);
      });
    }

    //索引限定
    function range(index, step, min, max){
      index += step;
      if( index > max){
        index = index - max - 1 + min;
      }
      if( index < min){
        index = max - (min - index - 1);
      }
      return index;
    }

    //修正
    function amend(obj){
      if(curImg === obj.children.length - 1){
        curImg = 1;
      }
      if(curImg === 0){
        curImg = obj.children.length - 2;
      }
      obj.style.left = - curImg * picWidth + 'px';
    }

    //自动播放
    function auto(){
      clearInterval(timer);
      timer = setInterval( () => {
        if(curImg === pics.children.length - 1){
          amend(pics);
        }
        curImg = range(curImg, 1, 0, pics.children.length - 1);
        dot = range(dot, 1, 0, ol.children.length - 1);
        dotStyle();
        animate(pics, - picWidth * curImg);
      },2000)
    }

    //鼠标悬浮图片区
    container.addEventListener('mouseenter',function(){
      clearInterval(timer);
    })
    container.addEventListener('mouseleave',function(){
      auto();
    })

    //是否正在进行动画
    function isAnimate(obj){
      if(obj.offsetLeft % picWidth){
        return true;
      }else{
        return false;
      }
    }

    //向左或者向右
    //参数:'left'  'right'
    function LOR(direction){
      if(isAnimate(pics)){
        return;
      }
      let step = null;
      if('left' === direction){
        step = -1;
      }else{
        step = 1;
      }

      if( 0 === curImg || pics.children.length - 1 === curImg){
        amend(pics);
      }

      curImg = range(curImg, step, 0, pics.children.length - 1);
      dot = range(dot, step, 0, ol.children.length - 1)
      dotStyle();
      animate(pics, - curImg * picWidth);
    }

    //点击向左
    left.addEventListener('click', function(){
      LOR('left');
    })
    //点击向右
    right.addEventListener('click', function(){
      LOR('right');
    })

    //初始化
    curImg = 1;
    dot = 0;
    dotStyle();
    animate(pics,- picWidth * curImg);
    auto();
  </script>
</body>
</html>

嗯,更新一下。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>circular8</title>
  <style>
    .container {
      width: 522px;
      height: 222px;
      box-sizing: border-box;
      padding: 10px;
      border: 1px solid gray;
      margin: auto;
      position: relative;
      top: 30px;
      overflow: hidden;
    }
    ul, ol {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    ul li {
      float: left;
    }
    .box {
      width: 500px;
      height: 200px;
      overflow: hidden;
      position: relative;
    }
    .pics {
      width: 1000%;
      position: absolute;
      left: -500px;
    }
    .box img {
      width: 500px;
      height: 200px;
      vertical-align: top;
    }
    .container ol {
      width: 500px;
      text-align: center;
      position: absolute;
      bottom: 20px;
    }
    .container ol li {
      width: 20px;
      height: 20px;
      line-height: 20px;
      display: inline-block;
      border-radius: 50%;
      background-color: #fff;
      color: #333;
      text-align: center;
      margin-right: 10px;
      cursor: pointer;
      user-select: none;
    }
    .container ol li:last-child {
      margin-right: 0;
    }
    .container ol li.cur {
      background-color: purple;
      color: #fff;
    }
    .container .left, .container .right {
      position: absolute;
      width: 40px;
      height: 60px;
      text-align: center;
      line-height: 60px;
      top: 111px;
      margin-top: -30px;
      background-color: rgba(0, 0, 0, .4);
      color: white;
      cursor: pointer;
      display: none;
      user-select: none;
    }
    .container:hover .left, .container:hover .right {
      display: block;
    }
    .container .left {
      left: 10px;
    }
    .container .right {
      right: 10px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="box">
      <ul class="pics">
        <li><img src="../images/1.jpg"></li>
        <li><img src="../images/2.jpg"></li>
        <li><img src="../images/3.jpg"></li>
        <li><img src="../images/4.jpg"></li>
        <li><img src="../images/5.jpg"></li>
      </ul>
    </div>
  </div>

  <script>
    let circular = {
      //各种变量
      container: null,
      pics: null,
      picsLen: null,
      ol: null,
      olLen: null,
      picWidth: null,
      left: null,
      right: null,
      timer: null,
      dot: 0,
      curImg: 1,
      //初始化
      init: function(container, pics){
        this.container = container;
        this.pics = pics;
        this.picWidth = this.pics.children[0].offsetWidth;
        this.pics.appendChild(this.pics.children[0].cloneNode(true));
        this.pics.insertBefore(this.pics.children[this.pics.children.length - 2].cloneNode(true), pics.children[0]);
        this.picsLen = this.pics.children.length;
        //生成小点
        this.ol = document.createElement('ol');
        for( let i = 0, len = this.picsLen - 2; i < len; i++){
          let li = document.createElement('li');
          li.innerHTML = i + 1;
          this.ol.appendChild(li);
        }
        this.container.appendChild(this.ol);
        this.olLen = this.ol.children.length;
        //定义 self 用于事件回调函数
        let self = this;
        //小点注册点击事件
        for( let i = 0; i < this.olLen; i++){
          this.ol.children[i].index = i;
          this.ol.children[i].addEventListener('click', function(){
            //修正位置
            let distance = self.picWidth * (self.picsLen - 2);
            if( self.picsLen - 1 === self.curImg){
              self.pics.style.left = self.pics.offsetLeft + distance + 'px';
            }
            if( 0 === self.curImg){
              self.pics.style.left = self.pics.offsetLeft - distance + 'px';
            }
            self.dot = this.index;
            self.curImg = this.index + 1;
            self.dotStyle();
            self.animate(self.pics, - self.picWidth * self.curImg);
          });
        }
        //生成左右按键
        this.left = document.createElement('div');
        this.left.className = 'left';
        this.left.innerHTML = '<';
        this.right = document.createElement('div');
        this.right.className = 'right';
        this.right.innerHTML = '>';
        this.container.appendChild(this.left);
        this.container.appendChild(this.right)
        //左右按键注册事件
        this.left.addEventListener('click', function(){
          self.LOR('left');
        });
        this.right.addEventListener('click', function(){
          self.LOR('right');
        });
        //鼠标悬停图片区
        this.container.addEventListener('mouseenter',function(){
          clearInterval(self.timer);
        });
        this.container.addEventListener('mouseleave',function(){
          self.auto();
        });
        //开始运行
        this.dot = 0;
        this.curImg = 1;
        this.dotStyle();
        this.animate(this.pics, - this.picWidth * this.curImg);
        this.auto();
      },
      //动画函数
      animate: function(obj, target){
        clearInterval(obj.timer);
        let step = Math.abs(target - obj.offsetLeft) / 62;
        let speed = target < obj.offsetLeft ? -step : step;
        obj.timer = setInterval(() => {
          let leftDistance = Math.abs(target - obj.offsetLeft);
          if(leftDistance < Math.abs(speed)){
            obj.style.left = target + 'px';
          }else{
            obj.style.left = obj.offsetLeft + speed + 'px';
          }
        }, 16);
      },
      //改变小点样式
      dotStyle: function(){
        for( let i = 0; i< this.olLen; i++){
          if(this.dot === i){
            this.ol.children[i].className = 'cur';
          }else{
            this.ol.children[i].className = '';
          }
        }
      },
      //索引限定
      range: function(index, step, min, max){
        index += step;
        index = index > max ? index - max - 1 + min : index;
        index = index < min ? max - (min - index - 1) : index;
        return index;
      },
      //修正
      amend: function(obj){
        this.curImg = this.curImg === obj.children.length - 1 ? 1 : this.curImg;
        this.curImg = this.curImg === 0 ? obj.children.length - 2 : this.curImg;
        this.pics.style.left = - this.picWidth * this.curImg + 'px';
      },
      //图片运动
      oneStep: function(step){
        this.curImg = this.range(this.curImg, step, 0, this.picsLen - 1);
        this.dot = this.range(this.dot, step, 0, this.olLen - 1);
        this.dotStyle();
        this.animate(this.pics, - this.picWidth * this.curImg);
      },
      //自动播放
      auto: function(){
        clearInterval(this.timer);
        this.timer = setInterval(() => {
          if(this.picsLen - 1 === this.curImg){
            this.amend(this.pics);
          }
          this.oneStep(1);
        }, 2000);
      },
      //是否正在进行动画
      isAnimate: function(obj){
        if(obj.offsetLeft % this.picWidth){
          return true;
        }else{
          return false;
        }
      },
      //向左或者向右
      //参数: 'left','right'
      LOR: function(direction){
        if(this.isAnimate(this.pics)){
          return;
        }
        let step = 'left' === direction ? -1 : 1;
        if( 0 === this.curImg || this.picsLen - 1 === this.curImg){
          this.amend(this.pics);
        }
        this.oneStep(step);
      }
    };
    circular.init(document.getElementsByClassName('container')[0], document.getElementsByClassName('pics')[0]);
  </script>
</body>
</html>

文章最初发布在简书,时间为 2018.07.23 21:40 。

链接:https://www.jianshu.com/p/580b93eb18a4