原生js实现轮播图的示例代码


Posted in Javascript onFebruary 20, 2017

很多网站上都有轮播图,但却很难找到一个系统讲解的,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出。

原理:

将一些图片在一行中平铺,然后计算偏移量再利用定时器实现定时轮播。

步骤一:建立html基本布局

如下所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>轮播图</title>
</head>
<body>
  <div class="container">
    <div class="wrap" style="left:-600px;">
      <img src="./img/5.jpg" alt="">
      <img src="./img/1.jpg" alt="">
      <img src="./img/2.jpg" alt="">
      <img src="./img/3.jpg" alt="">
      <img src="./img/4.jpg" alt="">
      <img src="./img/5.jpg" alt="">
      <img src="./img/1.jpg" alt="">
    </div>
    <div class="buttons">
      <span>1</span>
      <span>2</span>
      <span>3</span>
      <span>4</span>
      <span>5</span>
    </div>
    <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="arrow_left"><</a>
    <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="arrow_right">></a>
  </div>
</body>
</html>

 只有五张图片,却使用7张来轮播,这是为了实现无缝轮播,后面会详细介绍。

而5个span,即我们可以实时看到轮播图目前所处的位置。

最后是两个按钮,可以通过它来控制前进与后退。

这里我们需要对wrap使用绝对定位,所以用left:-600px;将第一张图片显示出来。

步骤二: css布局

首先,resetcss,如下所示:

* {
      margin:0;
      padding:0;
    }
    a{
      text-decoration: none;
    }

接着,我们为了让图片只在container中,所以需要限定其宽度和高度并且使用overflow:hidden;将其余的图片隐藏起来,并且我们希望wrap相对于container左右移动,所以设置为relative,如下:

.container {
      position: relative;
      width: 600px;
      height: 400px;
      margin:100px auto 0 auto;
      box-shadow: 0 0 5px green;
      overflow: hidden;
    }

我们设置wrap是绝对定位的,所以,我们就可以通过控制Left和Right来控制图片的移动了。设置z-index:1;以对后面将要放置的buttons作为参考。 因为共有七张图片,所以width为4200px(每张图片我们设置为600X400),我们只需让图片左浮动即可实现占满一排了。

.wrap {
      position: absolute;
      width: 4200px;
      height: 400px;
      z-index: 1;
    }

然后我们把图片设置位左浮动,并限定其大小,如下所示:

.container .wrap img {
      float: left;
      width: 600px;
      height: 400px;
    }

现在的效果如下:

原生js实现轮播图的示例代码    

即这时已经显示出了第一张图片。并且充满了整个container(container是有box-shadow的);

然后我们把显示次序的buttons放在图片的右下角。并且设置z-index:2;以保证buttons是在图片的上面的。 

.container .buttons {
      position: absolute;
      right: 150px;
      bottom:20px;
      width: 100px;
      height: 10px;
      z-index: 2;
    }

然后将buttons下面的span做一个简单的修饰,并且给和图片对应的span设置一个on类,如下: 

.container .buttons span {
      margin-left: 5px;
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background-color: green;
      text-align: center;
      color:white;
      cursor: pointer;
    }
    .container .buttons span.on{
      background-color: red;
    }

接下来,我们把左右切换的箭头加上,然后做简单的修饰,注意:因为这里使用实体来表示左右箭头,所以设置font-size才能改变其大小,

.container .arrow {
      position: absolute;
      top: 35%;
      color: green;
      padding:0px 14px;
      border-radius: 50%;
      font-size: 50px;
      z-index: 2;
      display: none;
    }
    .container .arrow_left {
      left: 10px;
    }
    .container .arrow_right {
      right: 10px;
    }
    .container:hover .arrow {
      display: block;
    }
    .container .arrow:hover {
      background-color: rgba(0,0,0,0.2);
    }

步骤三:添加js逻辑

我们首先获取到 wrap(因为要设置其left才能控制轮播图),然后获取到左右两个箭头,并实现手动轮播,如下: 

var wrap = document.querySelector(".wrap");
    var next = document.querySelector(".arrow_right");
    var prev = document.querySelector(".arrow_left");
    next.onclick = function () {
      next_pic();
    }
    prev.onclick = function () {
      prev_pic();
    }
    function next_pic () {
      var newLeft = parseInt(wrap.style.left)-600;
      wrap.style.left = newLeft + "px";
    }
    function prev_pic () {
      var newLeft = parseInt(wrap.style.left)+600;
      wrap.style.left = newLeft + "px";
    }

值得注意的是,这里wrap.style.left是一个字符串,所以要转化为数字才能进行计算,而设定left时就要加上px成为一个字符串了。

现在我们来测试一下:

原生js实现轮播图的示例代码 

可以看到,在第一页时,left值为-600,所以我们可以点击一次上一张,但是当再点击一次时,就出现了空白。同样的,下一张点击,到-3600是最后一张,就不能再继续点击了。

也就是说,当我们点击下一张到-3600px(这是第一张图片)时,我们需要下次跳转到第二张,即-1200px;这样才能正常跳转;

同理,当我们点击上一张到0px(这是第五张图片时),我们希望下次跳转到第四张,即-2400px;

按照这样的思路我们重新将next_pic和prev_pic函数修改如下: 

function next_pic () {
      var newLeft;
      if(wrap.style.left === "-3600px"){
        newLeft = -1200;
      }else{
        newLeft = parseInt(wrap.style.left)-600;
      }
      wrap.style.left = newLeft + "px";
    }
    function prev_pic () {
      var newLeft;
      if(wrap.style.left === "0px"){
        newLeft = -2400;
      }else{
        newLeft = parseInt(wrap.style.left)+600;
      }
      wrap.style.left = newLeft + "px";
    }

这时,我们就可以发现图片可以循环播放了!

但是,这时我们仅仅时手动循环播放的,我们如果希望自动播放,使用setInterval()即可,如下所示: 

var timer = null;
    function autoPlay () {
      timer = setInterval(function () {
        next_pic();
      },1000);
    }
    autoPlay();

即先设定一个计时器,然后创建一个可以自动播放的函数,最后调用这个函数即可。 现在它就可以自动播放了,效果如下:

原生js实现轮播图的示例代码

但是如果我们想要仔细看其中一个图片的时候,我们希望轮播图停止播放,只要clearInterval()即可,如下:

var container = document.querySelector(".container");
    container.onmouseenter = function () {
      clearInterval(timer);
    }
    container.onmouseleave = function () {
      autoPlay();  
    }

现在,只要我们把鼠标移入轮播图中,这时轮播图就不会播放了。而移开鼠标之后,轮播图自动播放。

但是到目前为止,轮播图下方的小圆点还没有动,现在我们就实现它。

原理很简单,即设置buttons的index初始值为0,即第一个span的class为on,然后触发next_pic函数时,index加1,当触发prev_pic函数时,inex减1, 并设置当前index的小圆点的class为on, 这就要求index必须设置为全局变量,才能保证它在每一个函数的作用域中。

添加showCurrentDot函数:

var index = 0;
    var dots = document.getElementsByTagName("span");
    function showCurrentDot () {
      for(var i = 0, len = dots.length; i < len; i++){
        dots[i].className = "";
      }
      dots[index].className = "on";
    }

在next_pic中添加代码:

index++;
      if(index > 4){
        index = 0;
      }

在prev_pic中添加大吗:

index--;
      if(index < 0){
        index = 4;
      }
      showCurrentDot();

这样,轮播图就可以自动切换,并且小圆点也在随着图片的变化而变化了。

但是,这距离我们经常看到的轮播图还有一定距离 - - - 当点击小圆点时, 就可跳转到相应图片。 实现原理即:  点击小圆点,就使wrap的Left变成相应的值。代码如下:

 

for (var i = 0, len = dots.length; i < len; i++){
      (function(i){
        dots[i].onclick = function () {
          var dis = index - i;
          if(index == 4 && parseInt(wrap.style.left)!==-3000){
            dis = dis - 5;   
          }
          //和使用prev和next相同,在最开始的照片5和最终的照片1在使用时会出现问题,导致符号和位数的出错,做相应地处理即可
          if(index == 0 && parseInt(wrap.style.left)!== -600){
            dis = 5 + dis;
          }
          wrap.style.left = (parseInt(wrap.style.left) + dis * 600)+"px";
          index = i;
          showCurrentDot();
        }
      })(i);      
    }

原理就是当点击到小圆点时,得到相应的i值,这个i值也就是span的index值,我们拿他和全局变量index作比较,然后重新设置wrap.style.left的值,然后把i值复制给全局变量index,最后显示当前的小原点即可。值得注意的是:这里涉及到了闭包的概念,如果直接使用for循环,则不能得到正确的结果。

最终效果如图:

原生js实现轮播图的示例代码  

最终代码如下所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>轮播图</title>
  <style>
    * {
      margin:0;
      padding:0;
    }
    a{
      text-decoration: none;
    }
    .container {
      position: relative;
      width: 600px;
      height: 400px;
      margin:100px auto 0 auto;
      box-shadow: 0 0 5px green;
      overflow: hidden;
    }
    .container .wrap {
      position: absolute;
      width: 4200px;
      height: 400px;
      z-index: 1;
    }
    .container .wrap img {
      float: left;
      width: 600px;
      height: 400px;
    }
    .container .buttons {
      position: absolute;
      right: 5px;
      bottom:40px;
      width: 150px;
      height: 10px;
      z-index: 2;
    }
    .container .buttons span {
      margin-left: 5px;
      display: inline-block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background-color: green;
      text-align: center;
      color:white;
      cursor: pointer;
    }
    .container .buttons span.on{
      background-color: red;
    }
    .container .arrow {
      position: absolute;
      top: 35%;
      color: green;
      padding:0px 14px;
      border-radius: 50%;
      font-size: 50px;
      z-index: 2;
      display: none;
    }
    .container .arrow_left {
      left: 10px;
    }
    .container .arrow_right {
      right: 10px;
    }
    .container:hover .arrow {
      display: block;
    }
    .container .arrow:hover {
      background-color: rgba(0,0,0,0.2);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="wrap" style="left: -600px;">
      <img src="./img/5.jpg" alt="">
      <img src="./img/1.jpg" alt="">
      <img src="./img/2.jpg" alt="">
      <img src="./img/3.jpg" alt="">
      <img src="./img/4.jpg" alt="">
      <img src="./img/5.jpg" alt="">
      <img src="./img/1.jpg" alt="">
    </div>
    <div class="buttons">
      <span class="on">1</span>
      <span>2</span>
      <span>3</span>
      <span>4</span>
      <span>5</span>
    </div>
    <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="arrow arrow_left"><</a>
    <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="arrow arrow_right">></a>
  </div>
  <script>
    var wrap = document.querySelector(".wrap");
    var next = document.querySelector(".arrow_right");
    var prev = document.querySelector(".arrow_left");
    next.onclick = function () {
      next_pic();
    }
    prev.onclick = function () {
      prev_pic();
    }
    function next_pic () {
      index++;
      if(index > 4){
        index = 0;
      }
      showCurrentDot();
      var newLeft;
      if(wrap.style.left === "-3600px"){
        newLeft = -1200;
      }else{
        newLeft = parseInt(wrap.style.left)-600;
      }
      wrap.style.left = newLeft + "px";
    }
    function prev_pic () {
      index--;
      if(index < 0){
        index = 4;
      }
      showCurrentDot();
      var newLeft;
      if(wrap.style.left === "0px"){
        newLeft = -2400;
      }else{
        newLeft = parseInt(wrap.style.left)+600;
      }
      wrap.style.left = newLeft + "px";
    }
    var timer = null;
    function autoPlay () {
      timer = setInterval(function () {
        next_pic();
      },2000);
    }
    autoPlay();

    var container = document.querySelector(".container");
    container.onmouseenter = function () {
      clearInterval(timer);
    }
    container.onmouseleave = function () {
      autoPlay();  
    }

    var index = 0;
    var dots = document.getElementsByTagName("span");
    function showCurrentDot () {
      for(var i = 0, len = dots.length; i < len; i++){
        dots[i].className = "";
      }
      dots[index].className = "on";
    }

    for (var i = 0, len = dots.length; i < len; i++){
      (function(i){
        dots[i].onclick = function () {
          var dis = index - i;
          if(index == 4 && parseInt(wrap.style.left)!==-3000){
            dis = dis - 5;   
          }
          //和使用prev和next相同,在最开始的照片5和最终的照片1在使用时会出现问题,导致符号和位数的出错,做相应地处理即可
          if(index == 0 && parseInt(wrap.style.left)!== -600){
            dis = 5 + dis;
          }
          wrap.style.left = (parseInt(wrap.style.left) + dis * 600)+"px";
          index = i;
          showCurrentDot();
        }
      })(i);      
    }
  </script>
</body>
</html>

 总结:

实现一个轮播图还是不难的,大体思路: 先创建一个div,限定其宽度和高度,overflow:hidden。然后创建一个装图片的div,宽度为所有图片的总宽度,并且使其浮动,这样所有的图片就处于一行中。然后为了实现无缝滚动,所以需要在首尾分别添加一张过渡图片。 先添加两个按钮, 使其可以手动轮播,然后只需要添加一个定时器使其朝一个方向自动轮播即可,因为用户有时需要查看详情,所以当鼠标进入时就clear定时器,滑出再定时播放。为了更好地用户体验,我们再下面添加了一排小圆点,用户可以清楚地知道现在所处的位置, 最后, 利用闭包使得用户可以直接通过点击小圆点切换图片。

Javascript 相关文章推荐
js change,propertychange,input事件小议
Dec 20 Javascript
javascript引擎长时间独占线程造成卡顿的解决方案
Dec 03 Javascript
javascript动态添加删除tabs标签的方法
Jul 06 Javascript
轻松掌握JavaScript代理模式
Aug 26 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
Sep 01 Javascript
Js apply方法详解
Feb 16 Javascript
vue学习笔记之指令v-text &amp;&amp; v-html &amp;&amp; v-bind详解
May 12 Javascript
js仿微信抢红包功能
Sep 25 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
Nov 29 Javascript
微信小程序3D轮播实现代码
Sep 19 Javascript
node.js express框架实现文件上传与下载功能实例详解
Oct 15 Javascript
JS中this的4种绑定规则详解
Feb 04 Javascript
深入理解Javascript中的观察者模式
Feb 20 #Javascript
浅谈js中function的参数默认值
Feb 20 #Javascript
angularJS+requireJS实现controller及directive的按需加载示例
Feb 20 #Javascript
浅谈js函数三种定义方式 &amp; 四种调用方式 &amp; 调用顺序
Feb 19 #Javascript
js 输入框 正则表达式(菜鸟必看教程)
Feb 19 #Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
Feb 19 #Javascript
基于Angular.js实现的触摸滑动动画实例代码
Feb 19 #Javascript
You might like
PHP操作xml代码
2010/06/17 PHP
php代码收集表单内容并写入文件的代码
2012/01/29 PHP
ThinkPHP实现事务回滚示例代码
2014/06/23 PHP
Laravel 4 初级教程之Pages、表单验证
2014/10/30 PHP
让你的网站可编辑的实现js代码
2009/10/19 Javascript
javascript+css 网页每次加载不同样式的实现方法
2009/12/27 Javascript
新浪微博字数统计 textarea字数统计实现代码
2011/08/28 Javascript
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
2013/04/17 Javascript
Jquery中LigerUi的弹出编辑框(实现方法)
2013/07/09 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
js 输入框 正则表达式(菜鸟必看教程)
2017/02/19 Javascript
原生JS实现 MUI导航栏透明渐变效果
2017/11/07 Javascript
webpack打包js文件及部署的实现方法
2017/12/18 Javascript
Element-ui table中过滤条件变更表格内容的方法
2018/03/02 Javascript
详解关于JSON.parse()和JSON.stringify()的性能小测试
2019/03/14 Javascript
React组件对子组件children进行加强的方法
2019/06/23 Javascript
javascript面向对象程序设计实践常用知识点总结
2019/07/29 Javascript
JavaScript实现图片合成下载的示例
2020/11/19 Javascript
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
python实现excel读写数据
2021/03/02 Python
python 实现数组list 添加、修改、删除的方法
2018/04/04 Python
Python 实现选择排序的算法步骤
2018/04/22 Python
Python如何将装饰器定义为类
2020/07/30 Python
Desigual德国官网:在线购买原创服装
2018/03/27 全球购物
商务英语专业应届毕业生求职信
2013/10/28 职场文书
服务员岗位责任制
2014/02/11 职场文书
签约仪式策划方案
2014/06/02 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
义和团口号
2014/06/17 职场文书
简单的辞职信模板
2015/05/12 职场文书
母亲节感言
2015/08/03 职场文书
先进工作者主要事迹材料
2015/11/03 职场文书
2019年暑期安全广播稿!
2019/07/03 职场文书
初中教务主任竞聘演讲稿(范文)
2019/08/20 职场文书
在Python中如何使用yield
2021/06/07 Python
mysql中数据库覆盖导入的几种方式总结
2022/03/25 MySQL