JS原生轮播图实现

作为一个PHP全栈攻城狮,不仅要会后端PHP和数据库,还要会前端JS。今天源码时代 PHP培训 学科老师要和大家分享一下JS原生编写轮播图的插件。 说起轮播图,很多人会选择使用各种插件,比如基于JQuery或其它框架的。不瞒大家,我也用过,甚至还用过Flash的轮播图。总体来说,用起来是比较简单,但是有一个非常严重的问题,那就是加载速度非常非常慢。

如果能自己使用JS原生写一个轮播图,不仅速度快,那感觉也是高大上,颇有高级前端工程师的feel啊。不过今天为了大家好理解,我们使用面向过程的代码编写(面向过程关注细节,方便理解原理;面向对象使用方便,但不方便新手理解)。

在开始编写之前我们需要准备几张测试图片,以及一些技术基础:JavaScript、HTML、CSS。为了方便测试,我们约定一下测试环境:三张相同大小的图片放在images目录中,所有的JS、HTML、CSS代码写在一个html文件中;由于使用了新的DOM API,所以建议使用chrome50以上版本的浏览器。

编写思路:
1)来三张图和三个按钮,将所有图片排成一行,将第一张复制一份放在最后(也可以全部复制放在后面,但只会用到第一张,重复出现一次三张图,一共六张图)
2)通过外边距偏移实现轮播
默认显示第1张图
第1次改变,第1张图移出,第2张图出现
第2次改变,第2张图移出,第3张图出现
第0次改变,第3张图移出,第4张图出现(第4张是第1张的复制,用户感觉是回到了第1张)
轮回,第0次改变,瞬间将移回第1张,由于第4张图和第1张一样,所以用户无法感觉这个变化,然后继续第1张图移出,第2张出现
...
3)给按钮添加点击事件
触发时停止自动播放,并切换到指定的图片

第一步:编写HTML和CSS
编写HTML:
三张图
三个按钮
编写CSS:
将所有图片排成一行
将按钮排到轮播图中间底部
设置按钮的状态样式
                
代码如下:
  1. <!DOCTYPE html>
  2.         <html>
  3.         <head>
  4.         <meta charset="UTF-8">
  5.         <title>轮播图1</title>
  6.         <style>
  7.         .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
  8.         .banner ul{margin:0;padding:0;list-style:none;}
  9.         .banner .list li{float:left;}
  10.         .banner .list img{display:block;width:100%;}
  11.         
  12.         .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
  13.         .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
  14.         .icos li.on{background:#f00;}
  15.         </style>
  16.         </head>
  17.         <body>
  18.         <div class="banner">
  19.         <ul class="list">
  20.                 <li><img src="images/01.jpg"></li>
  21.                 <li><img src="images/02.jpg"></li>
  22.                 <li><img src="images/03.jpg"></li>
  23.         </ul>
  24.         <ul class="icos">
  25.                 <li class="on">0</li>
  26.                 <li>1</li>
  27.                 <li>2</li>
  28.         </ul>
  29.         </div>
  30.         </body>
  31.         </html>
复制代码
第二步:编写JavaScript获取元素
获取轮播图片总数(用于计算显示轮回)
获取每屏宽度(用于计算每次偏移量)
        
代码:
  1. <script>
  2.         window.onload=function(){
  3.                 //获取所有元素
  4.                 var list=document.querySelector('.list');
  5.                 var icos=document.querySelectorAll('.icos li');
  6.                 var li=document.querySelectorAll('.list li');
  7.                 var len=li.length; //一共几张图
  8.                 var li_width=document.querySelector('.banner').clientWidth; //每张图的宽度
  9.                 list.innerHTML=list.innerHTML+list.innerHTML; //在列表最后添加一份,在展示最后一张切到第一张时实际展示的是刚添加的这张
  10.                 li=document.querySelectorAll('.list li'); //重新获取所有节点
  11.                 //为每一个li设置宽度
  12.                 for(var i=0;i<li.length;i++){
  13.                         li[i].style.width=li_width+'px';
  14.                 }
  15.                 list.style.width=li_width*li.length+"px"; //设置总宽度,让所有图片在一行显示
  16.         }
  17.         </script>
复制代码
       
第三步:实现轮播
设置定时器实现隔3秒切换一张图片
切换图片时,需要传入切换到指定图片的编号
计算偏移量
设置定时器实现偏移时的动画效果
实现按钮状态同步变化
        
        JS代码:
  1. //通过偏移实现动画
  2.         function show(n){
  3.                 if(n==1){ //这个判断顺序很关键,必须放在上面,实现最后一张瞬间切回第一张,再转到第二张
  4.                         list.style.marginLeft='0px';
  5.                 }
  6.                 /*
  7.                 默认出现第1张
  8.                 n=1        动画出现第二张,第一张消失
  9.                 n=2        动画出现第三张,第二张消失
  10.                 n=0        动画出现第四张(第一张的复制),第三张消失
  11.                 n=1        瞬间切回第一张(由于第一张和第四张相同,肉眼看不出变化),再动画出现第二张,第一张消失
  12.                 */
  13.                 
  14.                 var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //计算偏移量,以实现动画效果,等于0时特殊处理,展示手动加的那一张
  15.                 var step=20; //步长可根据宽度计算得到
  16.                 var i=step;
  17.                 var timer=setInterval(function(){
  18.                         list.style.marginLeft=(w-i)+'px';
  19.                         i+=step;
  20.                         if(i>li_width){ //显示完一张图就停止
  21.                                 clearInterval(timer);
  22.                         }
  23.                 },20);
  24.                 
  25.                 //改变按钮状态
  26.                 for(var j=0; j<icos.length; j++){
  27.                         if(n==j){
  28.                                 icos[j].className='on';
  29.                         }else{
  30.                                 icos[j].className='';
  31.                         }
  32.                 }
  33.         }
  34.         
  35.         //自动播放函数
  36.         function autoplay(){
  37.                 var count=1; //初始是第1张,自动播放从第2张开始
  38.                 timeId=setInterval(function(){
  39.                         show(count % len); //取余数实现轮流播放
  40.                         count++;
  41.                 },3000);
  42.         }
  43.         
  44.         autoplay();
复制代码
第四步:按钮功能
给所有按钮添加事件
点击时停止自动播放,切换到指定的图片
        
JS代码:
  1. //给每一个按钮绑定事件
  2.         for(var i=0; i<icos.length; i++){
  3.                 icos[i].onmouseover=function(){ //鼠标移到小图标上时取消自动播放并切换到指定的图片上
  4.                         clearInterval(timeId);
  5.                         show(this.innerText);
  6.                 }
  7.                 icos[i].onmouseout=function(){ //鼠标移开时继续自动播放
  8.                         autoplay();
  9.                 }
  10.         }
复制代码
代码汇总:
  1. <!DOCTYPE html>
  2. <html>
  3.         <head>
  4.                 <meta charset="UTF-8">
  5.                 <title>轮播图1</title>
  6.                 <style>
  7.                         .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
  8.                         .banner ul{margin:0;padding:0;list-style:none;}
  9.                         .banner .list li{float:left;}
  10.                         .banner .list img{display:block;width:100%;}
  11.                         
  12.                         .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
  13.                         .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
  14.                         .icos li.on{background:#f00;}
  15.                 </style>
  16.         </head>
  17.         <body>
  18.                 <div class="banner">
  19.                         <ul class="list">
  20.                                 <li><img src="images/01.jpg"></li>
  21.                                 <li><img src="images/02.jpg"></li>
  22.                                 <li><img src="images/03.jpg"></li>
  23.                         </ul>
  24.                         <ul class="icos">
  25.                                 <li class="on">0</li>
  26.                                 <li>1</li>
  27.                                 <li>2</li>
  28.                         </ul>
  29.                 </div>
  30.                 
  31.                 <script>
  32.                         window.onload=function(){
  33.                                 //获取所有元素
  34.                                 var list=document.querySelector('.list');
  35.                                 var icos=document.querySelectorAll('.icos li');
  36.                                 var li=document.querySelectorAll('.list li');
  37.                                 var len=li.length; //一共几张图
  38.                                 var li_width=document.querySelector('.banner').clientWidth; //每张图的宽度
  39.                                 list.innerHTML=list.innerHTML+list.innerHTML; //在列表最后添加一份,在展示最后一张切到第一张时实际展示的是刚添加的这张
  40.                                 li=document.querySelectorAll('.list li'); //重新获取所有节点
  41.                                 
  42.                                 //为每一个li设置宽度
  43.                                 for(var i=0;i<li.length;i++){
  44.                                         li[i].style.width=li_width+'px';
  45.                                 }
  46.                                 list.style.width=li_width*li.length+"px"; //设置总宽度,让所有图片在一行显示
  47.                                 
  48.                                 //给每一个按钮绑定事件
  49.                                 for(var i=0; i<icos.length; i++){
  50.                                         icos[i].onmouseover=function(){ //鼠标移到小图标上时取消自动播放并切换到指定的图片上
  51.                                                 clearInterval(timeId);
  52.                                                 show(this.innerText);
  53.                                         }
  54.                                         icos[i].onmouseout=function(){ //鼠标移开时继续自动播放
  55.                                                 autoplay();
  56.                                         }
  57.                                 }
  58.                                 
  59.                                 //通过偏移实现动画
  60.                                 function show(n){
  61.                                         if(n==1){ //这个判断顺序很关键,必须放在上面,实现最后一张瞬间切回第一张,再转到第二张
  62.                                                 list.style.marginLeft='0px';
  63.                                         }
  64.                                         /*
  65.                                         默认出现第1张
  66.                                         n=1        动画出现第二张,第一张消失
  67.                                         n=2        动画出现第三张,第二张消失
  68.                                         n=0        动画出现第四张(第一张的复制),第三张消失
  69.                                         n=1        瞬间切回第一张(由于第一张和第四张相同,肉眼看不出变化),再动画出现第二张,第一张消失
  70.                                         */
  71.                                         
  72.                                         var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //计算偏移量,以实现动画效果,等于0时特殊处理,展示手动加的那一张
  73.                                         var step=20; //步长可根据宽度计算得到
  74.                                         var i=step;
  75.                                         var timer=setInterval(function(){
  76.                                                 list.style.marginLeft=(w-i)+'px';
  77.                                                 i+=step;
  78.                                                 if(i>li_width){ //显示完一张图就停止
  79.                                                         clearInterval(timer);
  80.                                                 }
  81.                                         },20);
  82.                                         
  83.                                         //改变按钮状态
  84.                                         for(var j=0; j<icos.length; j++){
  85.                                                 if(n==j){
  86.                                                         icos[j].className='on';
  87.                                                 }else{
  88.                                                         icos[j].className='';
  89.                                                 }
  90.                                         }
  91.                                 }
  92.                                 
  93.                                 //自动播放函数
  94.                                 function autoplay(){
  95.                                         var count=1; //初始是第1张,自动播放从第2张开始
  96.                                         timeId=setInterval(function(){
  97.                                                 show(count % len); //取余数实现轮流播放
  98.                                                 count++;
  99.                                         },3000);
  100.                                 }
  101.                                 
  102.                                 autoplay();
  103.                         }
  104.                 </script>
  105.         </body>
  106. </html>
复制代码

总结,和所有的PHP框架一样,所有JS框架和库都是基于原生JS编写的,只有把原生JS的代码掌握好,才能以不变应万变,在技术领域平静对待各种变化。

本文来源:http://bbs.itsource.cn/thread-1662-1-1.html,转载请注明出处!

猜你喜欢

转载自blog.csdn.net/villainy13579/article/details/78281650