用js数组实现最原始的图片轮播实现
上班以来看到了,写了很多的轮播图效果,实现方法大致有
1.将图片局对定位,利用z-index和opacity实现图片渐现
2.用css3 的transtion:Xx xx left/right,实现左右方向滑动轮播(淘宝)
3.在图片组的前后,各加一张图片,实现无缝连接
4.通过改变图片组外层的margin或者left值实现
今天我要写的是第四种,现在概观大部分网站,已经几乎没有这种实现方法了,因为逻辑比较复杂,而且比较消耗性能(需要不停的修改数组,然后遍历到页面上),今天写它的目的,只是想要挑战下自己,因为真的很久没有写过了
首先,先明确下实现思路
1.初始状态,如下图
红色是显示区域,需要设置overflow:hidden控制只显示一张
黑色的是四张图片,通过浮动,变成一排
html,css代码如下
body,div{ padding:0; margin:0; } .container{ width:560px; margin:50px auto; overflow:hidden; position: relative; } .after:after{ display: block; clear:both; content:''; } .img-box{ list-style: none; padding:0; width:calc(560px*4); margin-left:0; } .img-box li{ float:left; } .dot{
position: absolute;
bottom:30px;
margin:auto;
left:0;
right:0;
padding:0;
}
.dot li{
list-style: none;
padding:0;
float:left;
width:30px;
height:30px;
text-align: center;
line-height:30px;
border-radius: 50%;
background:#ccc;
color:#333;
margin-left:5px;
cursor:pointer;
}
.dot li:hover{
background:#666;
color:#fff;
}
.dot li.current{
background:#666;
color:#fff;
}
<div class='container'> <ul class='img-box after'> <li> <img src="imgs/1.png" alt=""> </li> <li> <img src="imgs/2.png" alt=""> </li> <li> <img src="imgs/3.png" alt=""> </li> <li> <img src="imgs/4.png" alt=""> </li> </ul>
<ul class='dot after'>
<li class='current'>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul> </div>
2,通过改变ul的margin-left值来实现图片移动,每隔固定的时间改变ul的margin值为图片的宽度
可是当移动到最后一张时,后面没有图片了,就会一片空白。
如果加上判断:移动到最后一张时,再进行移动就默认移入到第一张,虽然可以实现,但是效果很差,不是我想要的效果
利用js的数组可以实现预期的效果:
向左移动:
1.将轮播图的图片地址储存到数组arr中
2.每轮播一次,就将第一张图片放到最后,在数组中对应,将数组中的第一个元素删除,拼接到最后一个,将数组遍历到页面上;
3.重新设置margin-left为0;
如下图:
向右移动(ul向右移动):
向右移动和想左不同:
首先将最后一张图片放到最前面,对应数组就是将数组中最后一个元素删除拼接到arr的最前面,
然而此时ul的margin-left仍然是0;所以要将ul的margin-left改为负的图片宽度,(虽然移动了ul但是只是一瞬间的,而且当前图片没有变化)
最后将ul向右移动至margin-left改变至0;完成向右移动
思路明确后就可以一步一步的向下做了
1.首先实现自动轮播(每次想左轮播一张图片)
2.然后实现点击索引值轮播(想左轮播不止一张图片)
3.点击索引值实现向右轮播
js代码如下:
$(document).ready(function(){ var scroll={ ImgArr:[],//储存图片地址的数组 timer:null,//第一个定时器,表示每隔一段时间,轮播一次 distance:0,//轮播的距离 interval:20,//每段动画的时间 time:2000,//每段轮播的总时间 JG:4000,//每段轮播停留的时间 FIRST:1, current:1, timer2:null,//第二个定时器,轮播时的动画 init:function(){ var me=this; me.calc();//计算下面索引所占的宽度 me.timer=setInterval(function(){//自动轮播 me.change_dot();//改变索引的状态 me.next(1);//每次轮播一张 },me.JG) $(".dot li").mouseover(function(){//鼠标停留时,停止自动轮播 clearInterval(me.timer); }) $(".dot li").click(function(){ clearInterval(me.timer); me.timer=null; console.log(me.timer2); var num=$(this).text(); me.current=$(".dot li.current").text(); var step=num-me.current; if(me.timer2===null){//只有当轮播结束时才能进行第二次轮播,以防止出现bug if(step>0){ me.next(step); }else if(step<0){ me.prev(step); } $(".dot li").removeClass("current"); $(this).addClass("current"); } }) }, sort_arr:function(step){//滚动后重新排列数组 var me=this; for(var n=0;n<$(".container li img"). length;n++){ me.ImgArr[n]=$(".container li img").eq(n).attr("src"); } var html=''; var slice=me.ImgArr.slice(0,step); me.ImgArr=me.ImgArr.concat(slice); me.ImgArr.splice(0,step); for(var i=0;i<me.ImgArr.length;i++){ html+="<li><img src="+me.ImgArr[i]+"></li>"; } $(".container .img-box").html(""); $(".container .img-box").append(html); }, change_dot:function(){ var arr=$(".img-box li img").eq(0).attr("src").split("/"); console.log(arr[arr.length-1].split(".")[0]); var num=arr[arr.length-1].split(".")[0]; if(num=='4'){ num=0; } $(".dot li").removeClass("current"); $(".dot li").eq(num).addClass("current"); }, next:function(step){//向左移动 var me=this; me.distance=$(".container li img").eq(0).width(); var times=me.time/me.interval; var smalldistance=(me.distance*step)/times; me.timer2=setInterval(function(){ if(me.FIRST<=times){ $(".container .img-box").css("margin-left",'-'+me.FIRST*smalldistance+"px"); me.FIRST++; }else{ clearInterval(me.timer2) me.timer2=null; me.FIRST=1; $(".container .img-box").css("margin-left","0") me.sort_arr(step); } },me.interval) }, prev:function(step){//向右移动 var me=this; me.distance=$(".container li img").eq(0).width(); var length=$(".container .img-box li").length; for(var n=0;n<$(".container li img"). length;n++){ me.ImgArr[n]=$(".container li img").eq(n).attr("src"); } var slice_arr=me.ImgArr.slice(me.ImgArr.length+step); for(var m=1;m<=-step;m++){ $(".container li").eq(length-m).remove(); } var html=""; for(var i=0;i<slice_arr.length;i++){ html+="<li><img src="+slice_arr[i]+"></li>"; } $(".container .img-box").prepend(html); $(".container .img-box").css("margin-left",step*me.distance+'px'); me.distance=$(".container li img").eq(0).width(); var times=me.time/me.interval; var smalldistance=(me.distance*step)/times;//每次移动的小段距离 me.timer2=setInterval(function() { if(me.FIRST<=times){ var px=me.FIRST*smalldistance $(".container .img-box").css("margin-left",step*me.distance-me.FIRST*smalldistance+"px"); me.FIRST++; }else{//轮播结束时清楚定时器 clearInterval(me.timer2); me.timer 2=null; me.FIRST=1; $(".container .img-box").css("margin-left","0") } },me.interval) }, calc:function(){ var length=$(".dot li").length; var every=parseInt($(".dot li").eq(0).width())+parseInt($(".dot li").eq(0).css("margin-left")) $(".dot").width(every*length); } } scroll.init(); })