原生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 相关文章推荐
js css样式操作代码(批量操作)
Oct 09 Javascript
cnblogs 代码高亮显示后的代码复制问题解决实现代码
Dec 14 Javascript
jQuery插件jquery-barcode实现条码打印的方法
Nov 25 Javascript
理解js对象继承的N种模式
Jan 25 Javascript
jQuery Validation Plugin验证插件手动验证
Jan 26 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
Dec 15 Javascript
AngularJS 霸道的过滤器小结
Apr 26 Javascript
Vue实现搜索 和新闻列表功能简单范例
Mar 16 Javascript
JavaScript 日期时间选择器一些小结
Apr 02 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
Vue实现Layui的集成方法步骤
Apr 10 Javascript
Vue微信公众号网页分享的示例代码
May 28 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
编译问题
2006/10/09 PHP
Smarty中调用FCKeditor的方法
2014/10/27 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
Javascript中 关于prototype属性实现继承的原理图
2013/04/16 Javascript
JQuery遍历json数组的3种方法
2014/11/08 Javascript
nodejs教程之入门
2014/11/21 NodeJs
jQuery中数据缓存$.data的用法及源码完全解析
2016/04/29 Javascript
AngularJS入门教程之表格实例详解
2016/07/27 Javascript
canvas 画布在主流浏览器中的尺寸限制详细介绍
2016/12/15 Javascript
JS实现浏览器打印、打印预览示例
2017/02/28 Javascript
微信小程序-横向滑动scroll-view隐藏滚动条
2017/04/20 Javascript
nodejs+mongodb+vue前后台配置ueditor的示例代码
2018/01/02 NodeJs
除Console.log()外更多的Javascript调试命令
2018/01/24 Javascript
Vue实现双向绑定的原理以及响应式数据的方法
2018/07/02 Javascript
深入理解Vue.js轻量高效的前端组件化方案
2018/12/10 Javascript
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
下载给定网页上图片的方法
2014/02/18 Python
Python比较两个图片相似度的方法
2015/03/13 Python
对python中使用requests模块参数编码的不同处理方法
2018/05/18 Python
python逆序打印各位数字的方法
2018/06/25 Python
python 画二维、三维点之间的线段实现方法
2019/07/07 Python
Scrapy框架基本命令与settings.py设置
2020/02/06 Python
Python reduce函数作用及实例解析
2020/05/08 Python
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
中东奢侈品市场:Coveti
2019/05/12 全球购物
澳大利亚床上用品、浴巾和家居用品购物网站:Bambury
2020/04/16 全球购物
意大利和国际奢侈品牌购物网站:Suitnegozi.com
2021/01/15 全球购物
高中生毕业自我鉴定
2013/10/10 职场文书
创建市级文明单位实施方案
2014/03/01 职场文书
槐乡的孩子教学反思
2014/04/27 职场文书
一份教室追逐打闹的检讨书
2014/09/27 职场文书
2014幼儿园教育教学工作总结
2014/12/17 职场文书
体育教师个人总结
2015/02/09 职场文书
Go语言设计模式之结构型模式
2021/06/22 Golang
python Django框架快速入门教程(后台管理)
2021/07/21 Python
使用Java去实现超市会员管理系统
2022/03/18 Java/Android