原生JS实现轮播图

177 阅读3分钟

ezgif-1-c2db11e1d7.gif

实现原理

利用定时器实现动画,将整个ul向左边移动,而只显示div部分区域。

1.png

html布局

将ul且套在div内,并使用radio代替小圆点,这样只设置一个小圆点为checked,更方便

  <div id="swap">
    <span id="left"><</span>
    <span id="right">></span>
    <div id="lbt">
      <ul id="sliderul">
        <li>
          <img src="./IMG/img1"/>
        </li>
        <li>
          <img src="./IMG/img2"/>
        </li>
        <li>
          <img src="./IMG/img3"/>
        </li>
        <li>
          <img src="./IMG/img4"/>
        </li>
        <li>
          <img src="./IMG/img5"/>
        </li>
        <li>
          <img src="./IMG/img1"/>
        </li>
      </ul>
    </div>
    <div id="box_dots">
      <input type="radio" name="dots" id="1" checked>
      <input type="radio" name="dots" id="2">
      <input type="radio" name="dots" id="3">
      <input type="radio" name="dots" id="4">
      <input type="radio" name="dots" id="5">
    </div>
  </div>
</div>
css样式

设置轮播图的外层div的宽为一张图片的宽度,多余部分隐藏即可,而ul的宽度为整套图片的宽度。

#box{
	width:1400px;
	height: 500px;
	position:absolute;
}
#swap{
	width:810px;
	margin:50px auto;
	position:relative; 
}
#lbt{
	width: 700px;
	margin:10px auto;
	overflow:hidden;
	position:relative;
}
ul{
	width: 4200px;
	height: 270px;
	position:relative;
	left:0;
}
li{
	float: left;
	list-style-type: none;
}
img{
	width:700px;
}
#left,#right{
	width: 50px;
	height: 100px;
	font-size: 50px;
	padding-top: 15px;
	position:relative;
	z-index: 2;
}
#left{
	float: left;
	top:90px;
}
#right{
	float:right;
	top:90px;
}
#left:hover,#right:hover{
	background-color: rgba(151, 143, 143,0.5);
}
#box_dots{
	width:fit-content;
	position:relative;
}
js部分

先将小圆点布局设置居中。利用js设置可以动态满足小圆点布局居中。

    (swap.clientWidth - box_dots.clientWidth) / 2 + "px";

为函数添加参数flag,当flag为true时,向左;false时,向右。由于左右轮播图片的方向不一样,因此需要flag进行判断对图片的left样式是+或是-

利用setInterval设置轮播动画,将一张图片分为一小段一小段,隔一段时间向左移动一小部分

在这里,设置一次轮播总行度为一张图片的长度700;一张图片的总的轮播时间为1000ms,轮播一小部分图片之后间隔时间为50ms。由此可以计算出每一次轮播的一小部分的长度。为了保证每一次轮播时不被上一次轮播的定时器影响,在定时器开始时,将上一个定时器关闭,而当前定时器生效时,需要对图片进行轮播移动,当移动了一张图片的距离时,停止计时,并设置小圆点的checked值。

1.png

    let longAll = 700; //轮播总长度
    let timeAll = 1000; //总时间
    let timeIn = 50; //中间间隔时间
    let moveLong = longAll / (timeAll / timeIn); //轮播长度间隔
    let beforeMoveLeft = ul.offsetLeft;
    let intervalID; //定时器ID
    if (!flag) {
      moveLong = -moveLong;
    }
    clearInterval(intervalID);
    intervalID = setInterval(() => {
      nowLeft = ul.offsetLeft;
      ul.style.left = nowLeft + moveLong + "px";
      if (Math.abs(ul.offsetLeft - beforeMoveLeft) >= 700) {
        let index = Math.abs(ul.offsetLeft / 700) % 5;
        dots[index].checked = true;
        clearInterval(intervalID);
      }
    }, timeIn);
  }

左边按钮点击事件:

当轮播到第一张图片时,需要将left值设置为最后一张图片的left值

    nowLeft = ul.offsetLeft;
    if (nowLeft >= 0) {
      ul.style.left = "-3500px";
    }
    move(true);
  };

右边按钮点击事件:

当轮播到本质上的最后一张图片时,需要将left值设置为第一张图片的left值

    nowLeft = ul.offsetLeft;
    if (nowLeft <= -3500) {
      ul.style.left = "0px";
    }
    move(false);
  };

小圆点点击事件:

    dots[i].onclick = function () {
      ul.style.left = i * -700 + "px";
    };
  }

一进入页面的开始动画设置如下:需要设置setTimeout延时器,3s执行一次向左的轮播动画。

    let dateBefore = Date.now();
    setInterval(function () {
      nowLeft = ul.offsetLeft;
      if (nowLeft <= -3500) {
        ul.style.left = "0px";
      }
      move(false);
    }, 3000);
  }
  startMove();