1.轮播的实现原理是怎样的(jquery)?
- 先简单想想要实现上面的效果html是应该如何写:
<div class="carousel">//容器就是看到的可视区域的大小
<ul class="ct-img-big clear">//用li包裹好图片
<li data-index=0 ><a href="">![](./img/1.png)</a></li>//举例下面五个li都一样
<li data-index=1 ></li>
<li data-index=2 ></li>
<li data-index=3 ></li>
<li data-index=4 ></li>
<li data-index=5 ></li>
</ul>
<a class="btn btn-next" href="">></a> //俩个按钮
<a class="btn btn-pre" href=""><</a>
<ul class="ct-img-small clear">可视区里的小图片用li包裹好img
<li class="active">![](./img/1-1.png)</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
- 写完html在想想css如何实现一个静态的滚动(主要部分):
.carousel{
position:relative;//可视区相对定位;
overflow: hidden;//因为下面的li浮动到一排,要把可视区的外的图片隐藏(重点)
}
.ct-img-big{
position:absolute;//大图的位置相对可视区绝对定位
}
.ct-img-big li{
float: left;//图片排在一排(别忘了清浮动)
}
.btn{
position: absolute;//根据可视区去调整按钮的位置
}
.ct-img-small{
position:absolute; //跟大图类似但要把小图都放在可视区里
}
.ct-img-small li{
float: left;
}
写完html跟css得到了如下的状态;
-
想想图片是如何跟动起来的
简单叙述上面的图片的意思:
1.当点击的下一张图片时通过改变ul的容器的left位置切换下一张图片;比如上图刚开始可视区看到的时1,点击按钮下一张改变ul的位置(图片的大小为200px),left:-200px;可视区变成第2张;
2.问题来了当可视区为第四张图片时再点下一张时没有图片了可视区显示白;而我们想显示的时第一张图;怎么办?
3.所以我们在后面添加第一张图;当点击下一张时,就会显示第一张图;这时在改变ul的left的位置,把这个ul原始的第一张图展示在可视区里;这样每次到第四张图时再点击就会通过ul的left重新回到第一张图;
4:点击上一张图道理也是一样给第一张图前面添加最后一张图;再次不在坠述;
- 看下js怎么写:
var $imgBig=$('.ct-img-big'),
$btnNext=$('.btn-next'),
$btnPre=$('.btn-pre'),
$CT = $('.carousel'),
$imgSmall=$('.ct-img-small');
$imgWidth=$imgBig.find('li').width();//获取图片的宽度;
$imgLength=$imgBig.children().length;//获取克隆前的图片的长度;
//拷贝第一张和最后一张;把最后一张图放在最前面;把最前面的图放在最后;
var $firstImg=$imgBig.find('li').first(),
$lastImg=$imgBig.find('li').last();
$imgBig.prepend($lastImg.clone());
$imgBig.append($firstImg.clone());
//设置imgBig clone后的宽度
$imgBig.width( $imgWidth*$imgBig.children().length)//这时的个数是添加完以后的个数
$imgBig.css({'left':'-='+$imgWidth+'px'})//把第一张图放入可视区
var pageIndex = 0 ; //img的下标;
var isAnimate = false//防止重复点击 上锁
$btnNext.on('click',function(e){
e.preventDefault();//阻止默认事件刷新
playNext()
})
$btnPre.on('click',function(e){
e.preventDefault()
playPre()
})
$imgSmall.find('li').on('click',function(){
var smallIdx= $(this).index();
if(smallIdx>pageIndex){
playNext(smallIdx-pageIndex)
}else if(smallIdx<pageIndex){
playPre(pageIndex-smallIdx)
}
})
function playNext(n){
var idx = n ||1;
if(isAnimate) return;
isAnimate = true;
$imgBig.animate({'left':'-='+ $imgWidth*idx+'px'},function(){//如果页数=图片的最后一个,就让图片回到第一张;即data-index=0;
pageIndex = pageIndex+idx;
if( pageIndex ===$imgLength ){
$imgBig.css({'left':'-'+$imgWidth+'px'})
pageIndex = 0;
}
isAnimate = false;
smallImg()
})
}
function playPre(n){
var idx = n ||1;
if(isAnimate) return;
isAnimate = true;
$imgBig.animate({'left':'+='+$imgWidth*idx+'px'},function(){
pageIndex=pageIndex-idx;
if(pageIndex<0){
$imgBig.css({'left':'-'+$imgWidth*$imgLength+'px'})
pageIndex = $imgLength-1;
}
isAnimate = false;
smallImg()
})
}
//设置小图的class
function smallImg(){
$imgSmall.children()
.removeClass('active')
.eq(pageIndex)
.addClass('active')
}
//自动轮播 鼠标进入鼠标离开
var timer =setInterval(function(){
playNext()
},2000);
$CT.hover(function(){
clearInterval(timer)
},function(){
timer =setInterval( function(){
playNext()
},2000)
})
代码中要注意几个地方:
1.防止重复点击;要设置lock;
2.改变的left的大小要算好;
3.点击小图要跟大图的下标同步;
2. 再看下怎么实现渐变的轮播:
- 首先也得先写好一个静态的渐变的轮播
跟无缝滚动差不多,只是大图图片不用并列排成一排;而是要重叠的放在一起;通过改变的display的显示出来
.ct-img-big{
position:relative;
}
.ct-img-big li{
position:absolute;
display: none;//都重合在一起并且隐藏起来;
}
如何淡入淡出?
利用.fadeOut()淡出,.fadeIn()淡入
参考fadeOut如何确定播放那张图
next: (pageIndex+1)% $imgLength
pre: (pageIndex+$imgLength-1)%$imgLength)
- 来看下js代码
<script>
var $imgBig=$('.ct-img-big'),
$btnNext=$('.btn-next'),
$btnPre=$('.btn-pre'),
$imgSmall=$('.ct-img-small'),
$imgs=$imgBig.children(),
$CT = $('.carousel'),
$imgLength=$imgBig.children().length;//获取图片的长度;
var pageIndex = 0 ; //img的下标;
var isAnimate = false//防止重复点击 上锁
$btnNext.on('click',function(e){
e.preventDefault();//阻止默认事件刷新
playNext()
})
$btnPre.on('click',function(e){
e.preventDefault()
playPre()
})
$imgSmall.find('li').on('click',function(){
var idx= $(this).index();
Play(idx)
})
Play(0);//执行函数时可视区显示为第一张图;
function Play(idx){//执行函数时可视区显示为第一张图;
if(isAnimate) return;
isAnimate = true;
$imgs.eq(pageIndex).fadeOut(400);
$imgs.eq(idx).fadeIn(400,function(){
isAnimate = false;
})
pageIndex = idx;//0
smallImg()
}
function playNext(){
Play((pageIndex+1)% $imgLength)//带个数试试~ 当点击按钮下一张时为play(1)
}
function playPre(){
Play((pageIndex+$imgLength-1)%$imgLength)
}
//设置小图class
function smallImg(){
$imgSmall.children()
.removeClass('active')
.eq(pageIndex)
.addClass('active')
}
// 自动播放 鼠标进入停止一开 又开始自动播放
var timer =setInterval(function(){
playNext()
},2000);
$CT.hover(function(){
clearInterval(timer)
},function(){
timer =setInterval( function(){
playNext()
},2000)
})
</script>
3.看下css怎么实现轮播?
- 重点1:
.ct-img-big li
{
width:400px;
height: 200px;
float: left; //把图片横排排列起来;
}
.wrap
{
width: 400px;
height: 200px;
overflow: hidden;//隐藏可视区外的图片
border:1px solid;
margin: 0 auto;
}
- 重点2:
关键帧的使用:
@keyframes animation/*关键帧*/
{
0%{left:0px;}
20%{left:-400px;}
40%{left:-800px;}
60%{left:-1200px;}
80%{left:-1600px;}
100%{left:-2000px;}
}
.ct-img-big
{
width: 2400px;
height: 200px;
position: relative;
left:0px;
animation-name:animation;/*指定由@keyframes描述的关键帧名称。*/
animation-iteration-count:infinite;/*置动画重复次数, 可以指定infinite无限次重复动画*/
animation-duration: 18s;/*设置动画一个周期的时长。*/
animation-direction:alternate;/*设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。normal | reverse | alternate | alternate-reverse*/
}
- 代码如下:
<body>
<style>
ul,li{
padding:0px;
margin: 0px;
list-style: none;
}
.wrap
{
width: 400px;
height: 200px;
overflow: hidden;
border:1px solid;
margin: 0 auto;
}
.ct-img-big
{
width: 2400px;
height: 200px;
position: relative;
left:0px;
animation-name:animation;/*指定由@keyframes描述的关键帧名称。*/
animation-iteration-count:infinite;/*置动画重复次数, 可以指定infinite无限次重复动画*/
animation-duration: 18s;/*设置动画一个周期的时长。*/
animation-direction:alternate;/*设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。normal | reverse | alternate | alternate-reverse*/
}
.ct-img-big li
{
width:400px;
height: 200px;
float: left;
}
@keyframes animation/*关键帧*/
{
0%{left:0px;}
20%{left:-400px;}
40%{left:-800px;}
60%{left:-1200px;}
80%{left:-1600px;}
100%{left:-2000px;}
}
</style>
</head>
<body>
<div class="wrap">
<ul class="ct-img-big clear">
<li data-index=0 ><a href="">![](./img/1.png)</a></li>
<li data-index=1 ><a href="">![](./img/2.png)</a></li>
<li data-index=2 ><a href="">![](./img/3.png)</a></li>
<li data-index=3 ><a href="">![](./img/4.png)</a></li>
<li data-index=4 ><a href="">![](./img/5.png)</a></li>
<li data-index=5 ><a href="">![](./img/6.png)</a></li>
</ul>
</div>
</body>
</html>
4. 看看原生js怎么实现无缝滚动
- 重点1:
大图使用的定位重叠在一起;通过运动框架改变的高度和z-index;来实现大图切换的;
#yd{
overflow:hidden;
}
.big{
position:relative;
}
.big li{
position:absolute;
top:0px;
left:0px;
overflow:hidden;
}
- 重点2 :
小图是浮动;改变li中的left距离实现小图切换;
.small li{
float:left;
}
- 难点1:
运动框架
function Move(obj,attr,iTarget)
{
clearInterval(obj.timer)
obj.timer=setInterval(function(){
var cur=0
if(attr=='opacity')
{
cur=Math.round(parseFloat(getStyle(obj,attr))*100)
}else
{
cur=parseInt(getStyle(obj,attr))
}
var speed =(iTarget-cur)/6
speed=speed>0?Math.ceil(speed):Math.floor(speed)
if(cur==iTarget)
{
clearInterval(obj.timer)
}else
{
if(attr=='opacity')
{
obj.style.filter='alpha(opacity:'+(cur+speed)+')'
obj.style.opacity=(cur+speed)/100
}else{
obj.style[attr]=cur+speed+'px'
}
}
},30)
}
- 难点2:
注意大小图的位置,小图显示不仅要跟大图相对应;还要在中间显示;
所以要通过判断去改变小图left的大小;下一张时,在倒数第2个图片是距离不一样;在上一张时,倒数第2张又跟其他的一样;所以注意left的距离设定
if(now==0)//根据大图位置改变小图位置;
{
Move(oUlSmall,'left',0)
}else if(now==aLiSmall.length-1)
{
Move(oUlSmall,'left',-(now-2)*aLiSmall[0].offsetWidth)
}else{
Move(oUlSmall,'left',-(now-1)*aLiSmall[0].offsetWidth)
}
- js全代码
//封装了一个运动框架 和一个getStyle函数
<script>
function getStyle(obj,name)
{
if(obj.currentStyle)
{
return obj.currentStyle[name]
}else
{
return getComputedStyle(obj,false)[name]
}
}
function Move(obj,attr,iTarget)
{
clearInterval(obj.timer)
obj.timer=setInterval(function(){
var cur=0
if(attr=='opacity')
{
cur=Math.round(parseFloat(getStyle(obj,attr))*100)
}else
{
cur=parseInt(getStyle(obj,attr))
}
var speed =(iTarget-cur)/6
speed=speed>0?Math.ceil(speed):Math.floor(speed)
if(cur==iTarget)
{
clearInterval(obj.timer)
}else
{
if(attr=='opacity')
{
obj.style.filter='alpha(opacity:'+(cur+speed)+')'
obj.style.opacity=(cur+speed)/100
}else{
obj.style[attr]=cur+speed+'px'
}
}
},30)
}
var oDiv = document.getElementById('yd')
var oBtnPrev =document.getElementsByClassName('prev')[0]
var oBtnNext =document.getElementsByClassName('next')[0]
var oLeft =document.getElementsByClassName('left')[0]
var oRight =document.getElementsByClassName('right')[0]
var oSmall=document.getElementsByClassName('small')[0]
var oUlSmall=oSmall.getElementsByTagName('ul')[0]
var aLiSmall=oSmall.getElementsByTagName('li')//小图li
var oBig=document.getElementsByClassName('big')[0]
var aLiBig=oBig.getElementsByTagName('li')//大图li
var nowZIndex=2;
var now=0
oUlSmall.style.width=aLiSmall.length*aLiSmall[0].offsetWidth+300+'px'//小图容器宽度;
//左右按钮
oLeft.onmouseover = oBtnPrev.onmouseover = function()
{
Move(oBtnPrev,'opacity',100)
}
oLeft.onmouseout=oBtnPrev.onmouseout = function()
{
Move(oBtnPrev,'opacity',0)
}
oRight.onmouseover= oBtnNext.onmouseover = function()
{
Move(oBtnNext,'opacity',100)
}
oRight.onmouseout=oBtnNext.onmouseout = function()
{
Move(oBtnNext,'opacity',0)
}
//小图切换
for(var i=0;i<aLiSmall.length;i++)
{
aLiSmall[i].index=i
aLiSmall[i].onclick=function()
{
if(this.index==now)return;
now=this.index
Tab()
}
if(this.index!=now)
{
Move(this,'opacity',60)
}
}
function Tab()//图片切换函数;
{
aLiBig[now].style.zIndex=nowZIndex++;//改变大图的z-index的大小切换图片;
for(var i=0;i<aLiSmall.length;i++)
{
Move(aLiSmall[i],'opacity',60)
}
Move(aLiSmall[now],'opacity',100)
aLiBig[now].style.height=0
Move(aLiBig[now],'height','500')//改变高度实现切换;高度0-500;
if(now==0)//根据大图位置改变小图位置;
{
Move(oUlSmall,'left',0)
}else if(now==aLiSmall.length-1)
{
Move(oUlSmall,'left',-(now-2)*aLiSmall[0].offsetWidth)
}else{
Move(oUlSmall,'left',-(now-1)*aLiSmall[0].offsetWidth)
}
}
//对于两个边界进行设定
oBtnPrev.onclick= function()
{
now--;
if(now==-1)
{
now=aLiSmall.length-1
}
Tab()
}
oBtnNext.onclick = function()
{
now++;
if(now==aLiSmall.length)
{
now=0
}
Tab()
}
var timer=setInterval(oBtnNext.onclick,2000)
oDiv.onmouseover= function()
{
clearInterval(timer)
}
oDiv.onmouseout= function()
{
timer=setInterval(oBtnNext.onclick,2000)
}
</script>
附上以上4个轮播的github地址
jquery轮播
jquery淡入淡出录播
css轮播
原生js轮播
希望对各位朋友对轮播这块有所帮助~~~
版权归饥人谷__楠柒所有,如要转载请请注明出处~