原生JS实现的轮播图功能详解


Posted in Javascript onAugust 06, 2018

本文实例讲述了原生JS实现的轮播图功能。分享给大家供大家参考,具体如下:

一、效果预览:

原生JS实现的轮播图功能详解

由于只能上传2M以下的图片,这里只截取了自动切换的效果:

二、编写语言

HTML、CSS、原生JS

三、编写思路

(一)HTML部分

1、.slide意为滑槽,里面存放所有图片;

2、.prev存放向左的箭头,.next存放向右的箭头;

3、pointer意为指示器,存放下方的五个切换按钮,每个切换按钮用span来表示;

4、.m-view,意为视窗,即每次看到图片的窗口,它存放以上所有的部件;

(二)CSS部分

1、.m-view设为相对定位,他的后代元素可以以它作为绝对定位的参照;

2、.slide.prev.nextpointer全都用绝对定位放到合适位置;

3、.slide的所有图片水平排列,且视窗.m-view的宽度设为只有一张图片那么宽,这样默认情况.slide还是会全部显示;当给.m-view设置overflow:hidden后子元素超出它的部分就会隐藏,就实现了只显示一张图片的效果;

(三)JS部分

1、切换功能:

设置一个切换函数toggle实现左切或者右切一张图,toggle有两个子函数leftTogglerightToggle分别实现向左、向右切换一张图,将他们分别绑定到.prev.next按钮的clik事件;

2、切换功能的淡入动画效果

只有1的话切换是立即产生的,没有过渡效果;这里利用定时器和步长将切换功能细化到更小的滑动操作leftSteprightStepleftTogglerightToggle通过多次调用滑动操作来实现一次切换,这样就会产生动画效果;

3、跳转功能

对指示器的每个圆形按钮绑定跳转功能,跳转实际上是将.slide进行移动;

4、自动播放

只需要设置定时器,每隔一定时间执行切换即可;

四、我的代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>轮播图</title>
  <style>
    .m-view,.m-view .slide img{
      position: relative;/*作为绝对定位的父元素*/
      width: 800px;
      height: 600px;
    }
    .m-view{
      overflow: hidden;/*将超出该div的子元素隐藏*/
    }
    .m-view .slide{
      position: absolute;
      width: 8000px;
      height: 600px;
    }
    .m-view .slide img{
      margin-right: -5px;
    }
    .m-view .prev,.m-view .next{
      position: absolute;
      top: 40%;
      font: 60px/60px Microsoft YaHei;
      color: #00BFFF;
    }
    .m-view .prev{
      left: 10px;
    }
    .m-view .next{
      right: 10px;
    }
    .m-view .pointer{
      position: absolute;
      bottom: 40px;
      left: 33%;
    }
    .m-view .pointer span{
      display: inline-block;/*水平排列*/
      width: 40px;
      height: 40px;
      border-radius: 20px;
      margin-right: 10px;
      background-color: #00FF00;
    }
    .m-view .pointer .on{/*点亮当前图片对应的圆圈*/
      background-color: #1E90FF;
    }
  </style>
</head>
<body>
  <div class="m-view">
    <div class="slide" style="left: -800px">
      <img src="../lunbo/5.jpg" alt="4">
      <img src="../lunbo/1.jpg" alt="0">
      <img src="../lunbo/2.jpg" alt="1">
      <img src="../lunbo/3.jpg" alt="2">
      <img src="../lunbo/4.jpg" alt="3">
      <img src="../lunbo/5.jpg" alt="4">
      <img src="../lunbo/1.jpg" alt="0">
    </div>
    <div class="prev"><</div>
    <div class="next">></div>
    <div class="pointer">
      <span class="button on" index="0"></span>
      <span class="button" index="1"></span>
      <span class="button" index="2"></span>
      <span class="button" index="3"></span>
      <span class="button" index="4"></span>
    </div>
  </div>
  <script type="text/javascript">
    var view=document.getElementsByClassName('m-view')[0];
    var slide=document.getElementsByClassName('slide')[0];
    var prev=document.getElementsByClassName('prev')[0];
    var next=document.getElementsByClassName('next')[0];
    var button=document.getElementsByClassName('button');
    var curIndex=0;//当前图片的索引位置
    var toggled=true;//是否正在切换,true表明切换已完成,此时才能切换
    /* Toggle函数实现切换一张图片的功能 */
    function Toggle () {
      var TIMER=50;//滑动一次所用的时间,它是setInterval的第二个参数
      var time=800;//每切换一张图片总共用的时长
      var times=time/TIMER;//每切换一张图片需滑动的次数
      var stepLenth=800/times;//每次滑动的步长
      var leftToggle=function () {
        var t1=times;
        function leftStep(){
          slide.style.left=parseInt(slide.style.left)+stepLenth+"px";
          t1--;
          if (!t1) {
            clearInterval(interval);
            curIndex--;
            if (curIndex<0) {
              slide.style.left=parseInt(slide.style.left)-4000+"px";
              curIndex=4;
            };
            toggled=true;
          };
        };
        if (toggled==true) {
          toggled=false;
          button[curIndex].className="button";
          if (curIndex!=0) {
            button[curIndex-1].className="button on";
          }else{
            button[curIndex+4].className="button on";
          }
          var interval=setInterval(leftStep,TIMER);
        };
      };
      var rightToggle=function () {
        var t2=times;
        function leftStep(){
          slide.style.left=parseInt(slide.style.left)-stepLenth+"px";
          t2--;
          if (!t2) {
            clearInterval(interval);
            curIndex++;
            if (curIndex>4) {
              slide.style.left=parseInt(slide.style.left)+4000+"px";
              curIndex=0;
            };
            toggled=true;
          };
        };
        if (toggled==true) {
          toggled=false;
          button[curIndex].className="button";
          if (curIndex!=4) {
            button[curIndex+1].className="button on";
          }else{
            button[curIndex-4].className="button on";
          };
          var interval=setInterval(leftStep,TIMER);
        };
      }
      this.leftToggle=leftToggle;//输出对外的接口
      this.rightToggle=rightToggle;
    };
    var toggle=new Toggle();
    prev.onclick=function () {
      toggle.leftToggle();
    };
    next.onclick=function () {
      toggle.rightToggle();
    };
    /* 点击圆圈跳转功能 */
    for (var i = 0; i < button.length; i++) {
      button[i].onclick=function () {
        var newIndex=parseInt(this.getAttribute("index"));
        if (newIndex!=curIndex) {
          var distance=-800*(newIndex-curIndex);
          slide.style.left=parseInt(slide.style.left)+distance+"px";
          button[curIndex].className="button";
          button[newIndex].className="button on";
          curIndex=newIndex;
        };
      };
    }
    /* 自动播放功能,鼠标移上去停止播放,移开再次播放 */
    var intervalo=setInterval(toggle.rightToggle,3000);
    view.onmouseover=function () {
      clearInterval(intervalo);
    }
    view.onmouseout=function () {
      intervalo=setInterval(toggle.rightToggle,3000);
    }
  </script>
</body>
</html>

五、一些总结

1、本次采用了面向对象和封装的思路,这是因为个人体会到确实面向对象的设计能使代码编写思路更加清晰,还能够免去很多冗余重复的代码,也尝试过其他书写思路,但都会使代码变得不太直观;要注意的一点就是封装后要向外提供接口,且如果是封装在一个函数中,需要实例化一个对象才能调用;

2、在.slide中设置了一个内联样式,这是因为在后面要获取并改变它的left属性,如果不采用内联样式的方法,将无法设置;因为初始时.style.left只能获取内联样式,即使采用内部样式和外部样式也会使得获取的值为undefined。当然,肯定也可以采用其他方法,但是似乎其他方案都更为复杂一些,没找到更简便的方法。

3、在前后各多放置一张图片的作用:
比如,当前是图片1,现在向左切换,可以和其他位置一样先执行统一的左移操作,这时视窗显示额外放置的图片5,再将.slide整体左移使真正的图片5显示在视窗中,这样是先出现了动画效果再“暗中移动”了.slide,就好像没移动一样,真正做到了无缝切换,逻辑也很简单;如果不放置额外的图片,就需要先将视窗左移,使图片5显示在视窗中,这样动画效果难以设置。

4、在获取每个span在它父元素的索引位置时,采用了getAttribute获取自定义的index属性的方法,其他方法肯定也有不少,但是肯定不能在循环中把i的值直接当成span的索引位置。

5、在跳转功能中,如果要跳转的正是当前的页面,应该什么也不做,这样可以优化性能 。

6、在点击左右箭头切换时,先判断上一次动画是否完成,没完成就不切换,这样可以优化性能,否则连续点击可能导致卡顿、切换效果不佳。

7、代码似乎还有可以优化的地方;

8、这个只是制作了一个轮播图,接下来考虑做一个轮播组件,似乎难度要大些,还有3D的轮播效果也想要尝试下了。

PS:感兴趣的朋友还可以将上述代码中的图片替换成网络图片,再使用如下在线工具在线测试运行效果:

HTML/CSS/JavaScript代码运行工具
http://tools.3water.com/code/HtmlJsRun

在线HTML/CSS/JavaScript前端代码调试运行工具
http://tools.3water.com/code/WebCodeRun

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
Jquery中getJSON在asp.net中的使用说明
Mar 10 Javascript
基于jquery实现状态限定编辑的代码
Feb 11 Javascript
Jquery实现简单的动画效果代码
Mar 18 Javascript
jquery三个关闭弹出层的小示例
Nov 05 Javascript
JS实现仿google、百度搜索框输入信息智能提示的实现方法
Apr 20 Javascript
微信支付 JS API支付接口详解
Jul 11 Javascript
jquery获取点击控件的绝对位置简单实例
Oct 13 Javascript
Angularjs分页查询的实现
Feb 24 Javascript
详解基于webpack和vue.js搭建开发环境
Apr 05 Javascript
React key值的作用和使用详解
Aug 23 Javascript
ES6知识点整理之Proxy的应用实例详解
Apr 16 Javascript
vue vant中picker组件的使用
Nov 03 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
Aug 06 #Javascript
animate.css在vue项目中的使用教程
Aug 05 #Javascript
iconfont的三种使用方式详解
Aug 05 #Javascript
vue-content-loader内容加载器的使用方法
Aug 05 #Javascript
vue+element-ui集成随机验证码+用户名+密码的form表单验证功能
Aug 05 #Javascript
dts文件中删除一个node或属性的操作方法
Aug 05 #Javascript
深入理解JavaScript的async/await
Aug 05 #Javascript
You might like
Cappuccino 卡布其诺咖啡之制作
2021/03/03 冲泡冲煮
咖啡知识 除了喝咖啡还有那些知识点
2021/03/06 新手入门
PHP 实现字符串翻转(包含中文汉字)的实现代码
2017/04/01 PHP
javascript语句中的CDATA标签的意义
2007/05/09 Javascript
js动态创建表格,删除行列的小例子
2013/07/20 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
Javascript基础教程之比较null和undefined值
2016/05/16 Javascript
深入理解jQuery layui分页控件的使用
2016/08/17 Javascript
jQuery实现获取元素索引值index的方法
2016/09/18 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
2016/09/28 Javascript
浅析Ajax语法
2016/12/05 Javascript
Bootstrap modal 多弹窗之叠加引起的滚动条遮罩阴影问题
2017/02/27 Javascript
Vue中添加过渡效果的方法
2017/03/16 Javascript
JS处理数据四舍五入(tofixed与round的区别详解)
2017/10/26 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
2018/09/07 Javascript
webpack4打包vue前端多页面项目
2018/09/17 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
js异步接口并发数量控制的方法示例
2020/11/22 Javascript
Python中顺序表的实现简单代码分享
2018/01/09 Python
Python使用selenium实现网页用户名 密码 验证码自动登录功能
2018/05/16 Python
python 使用while循环输出*组成的菱形实例
2020/04/12 Python
pycharm 实现光标快速移动到括号外或行尾的操作
2021/02/05 Python
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
2018/02/07 HTML / CSS
CSS3实现div从下往上滑入滑出效果示例
2020/04/28 HTML / CSS
TCP/IP的分层模型
2013/10/27 面试题
Java程序员面试题
2016/09/27 面试题
四议两公开实施方案
2014/03/28 职场文书
工商干部先进事迹
2014/05/14 职场文书
学校读书活动总结
2014/06/30 职场文书
政府个人对照检查材料
2014/08/28 职场文书
办理房产过户的委托书
2014/09/14 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
广告公司文案策划岗位职责
2015/04/14 职场文书
导游词之山东红叶谷
2019/10/31 职场文书
导游词之广西漓江
2019/11/02 职场文书
python 单机五子棋对战游戏
2022/04/28 Python