原生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的图片轮播 tab切换组件
Jul 19 Javascript
javascript中数组的sort()方法的使用介绍
Dec 18 Javascript
jQuery控制TR显示隐藏的几种方法
Jun 18 Javascript
javascript实现字符串反转的方法
Feb 05 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
很棒的一组js图片轮播特效
Jan 12 Javascript
d3.js入门教程之数据绑定详解
Apr 28 Javascript
vuejs手把手教你写一个完整的购物车实例代码
Jul 06 Javascript
vue脚手架中配置Sass的方法
Jan 04 Javascript
vue实现行列转换的一种方法
Aug 06 Javascript
VSCode搭建React Native环境
May 07 Javascript
基于JavaScript实现轮播图效果
Jan 02 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
php,不用COM,生成excel文件
2006/10/09 PHP
PHP 日志缩略名的创建函数代码
2010/05/26 PHP
php数组函数序列之array_keys() - 获取数组键名
2011/10/30 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
用javascript实现画板的代码
2007/09/05 Javascript
预加载css或javascript的js代码
2010/04/23 Javascript
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
jQuery中:checked选择器用法实例
2015/01/04 Javascript
jQuery预加载图片常用方法
2015/06/15 Javascript
跟我学习javascript的作用域与作用域链
2015/11/19 Javascript
js格式化输入框内金额、银行卡号
2016/02/01 Javascript
element ui里dialog关闭后清除验证条件方法
2018/02/26 Javascript
浅谈vue方法内的方法使用this的问题
2018/09/15 Javascript
React降级配置及Ant Design配置详解
2018/12/27 Javascript
通过实例解析vuejs如何实现调试代码
2020/07/16 Javascript
使用原生javascript开发计算器实例代码
2021/02/21 Javascript
[01:45:05]VGJ.T vs Newbee Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
python3访问sina首页中文的处理方法
2014/02/24 Python
pycharm 更改创建文件默认路径的操作
2020/02/15 Python
Python定义函数实现累计求和操作
2020/05/03 Python
Python之字典添加元素的几种方法
2020/09/30 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
html5写一个BUI折叠菜单插件的实现方法
2019/09/11 HTML / CSS
艺术应用与设计个人的自我评价
2013/11/23 职场文书
《掌声》教学反思
2014/02/23 职场文书
志愿者活动总结报告
2014/06/27 职场文书
住房租房协议书
2014/08/20 职场文书
大学生职业生涯十年规划书范文
2014/09/17 职场文书
毕业生自荐材料范文
2014/12/30 职场文书
培训通知
2015/04/17 职场文书
优质护理服务心得体会
2016/01/22 职场文书
2019各种承诺书范文
2019/06/24 职场文书
python 实现mysql自动增删分区的方法
2021/04/01 Python
Python Django ORM连表正反操作技巧
2021/06/13 Python
实现一个简单得数据响应系统
2021/11/11 Javascript