首先来分析一下轮播图效果的实现原理:
1、父元素作为显示窗口,大小固定超出部分隐藏,即设置overflow:hidden;
2、子元素存放图片列表用ul,ul固定定位,参照为父元素,即父元素position:relative;ul元素position:absolute;
3、一个li即一张图片的宽度为父元素的显示宽度
4、初始时,ul的left为0,这时第一张图片即第一个li显示
5、点击下一张按钮,将整个ul左移,使第二个li对齐父元素的左边框,此时ul的left为负的一个li的宽度
6、点击上一张按钮,将整个ul右移
7、对特殊情况进行处理,即第一张图时点上一张,最后一张图时点下一张
第一张图时点上一张,我们滚动到最后一张图,整个ul左移,即把left值改为负的n-1张图的宽度;
最后一张图时点下一张,我们滚到第一张图的位置,整个ul右移,即把left值改为0
用一张图来帮助理解:
修改ul元素的left值很简单ul.style.left=设定值,就可以了,但我们想有一个滑动的效果,那我们需要用setInterval来实现
最后的效果如下:(文章最后有封装好的方法)
动图不能录制太大CSDN有2M的限制_(:зゝ∠)_
下面放代码
关于上一页下一页按钮点击过快出现的bug想到了两种解决方法:
首先说一下出现bug的原因:问题出在goRoll方法里,停止定时器的条件是图片到达目标位置,快速点击导致这个位置判断存在问题。
解决方法1:点击按钮后将按钮隐藏,图片滚动完成再显示按钮
解决方法2:把prev.style.display="none"这种设置改成prev.οnclick=修改,这种需要把之前的onclick方法拿出来感觉写起来比方法1麻烦我就不写了
思路就是,当进入goRoll方法里,给两个按钮的点击方法清空,当轮播完成再给两个按钮加上图片滚动的正确方法
最后放上封装的方法:(采用解决方法1)
var nav=document.getElementById("nav").getElementsByTagName("li");
var img=document.getElementById("imgList");//ul父元素
var prev=document.getElementById("prev");//上一张
var next=document.getElementById("next");//下一张
imgRoll(img,prev,next,-10,870,3,0);
//封装图片轮播方法
//ulObj=ul元素,prvObj=上一张按钮,nextObj=下一张按钮,speed=速度(负值,比如-10),
// imgWidth=一张li的宽度(轮播元素的宽度),imgNum=li个数(轮播图片的个数),curIndex(当前图片序列号,0是从第一张图片开始),flag目前还没有用处可以忽略不传
//按钮点击后隐藏
function imgRoll(ulObj,prvObj,nextObj,speed,imgWidth,imgNum,curIndex,flag){ if(imgNum<=1){//如果只有一张图片不用轮播不显示上一页和下一页按钮 prvObj.style.display="none"; nextObj.style.display="none"; }else{ prvObj.style.display="block"; nextObj.style.display="block"; } var index=curIndex;//当前图片序列号 var endIndex=imgNum-1;//最后一张图片序列号 ulObj.style.left=-index*imgWidth+'px'; var timer;//定时器名字 var iSpeed=speed;//滚动的速度 function goRoll(){ prvObj.style.display="none"; nextObj.style.display="none"; timer=setInterval(function () { ulObj.style.left=ulObj.offsetLeft+iSpeed+'px'; var stop=-index*imgWidth+'px';//当达到目标位置时停止定时器 if(ulObj.style.left==stop){ iSpeed=speed; clearInterval(timer); if(index!=0){ prvObj.style.display="block"; } if(index!=imgNum-1){ nextObj.style.display="block"; } } },10) } if(index==0){ prvObj.style.display="none"; }else if(index==endIndex){ nextObj.style.display="none"; }else{ prvObj.style.display="block"; nextObj.style.display="block"; } //上一张和下一张点击效果 prvObj.οnclick= function () { index--; iSpeed=-speed; goRoll(); }; nextObj.οnclick= function () { index++; iSpeed=speed; goRoll(); }; }