- 该插件由轮播图片、向前向后按钮及底部分页器3部分组成
- 主要逻辑是以操作
dom
完成的,所有图片设置浮动,显示在同一行,即:
next
按钮:先显示,再移动;点击该按钮,图片列表向左移动,列表的left
值变小,当移动到被显示图片位置后,将被显示图片之前的图片append
至列表末尾,通过append
操作的元素是被移动而不是被复制
pre
按钮:先移动,再显示;点击该按钮,先将末尾图片prepend
至列表首位,这里和append
一样,是移动不是复制,这时列表再向右移动,left
值变大,移动至列表首位显示图片
- 先看
dom
结构
<div class="carousel">
<!-- 轮播图片 -->
<ul class="items clear">
<li>
<a href="javascript:void(0)">
<img src="imgs/2.jpg" alt="">
</a>
</li>
<li>
<a href="javascript:void(0)">
<img src="imgs/3.jpg" alt="">
</a>
</li>
<li>
<a href="javascript:void(0)">
<img src="imgs/4.jpg" alt="">
</a>
</li>
<li>
<a href="javascript:void(0)">
<img src="imgs/5.jpg" alt="">
</a>
</li>
</ul>
<!-- 向前向后按钮 -->
<a href="javascript:void(0)" class="pre"><</a>
<a href="javascript:void(0)" class="next">></a>
<!-- 分页器 -->
<ul class="bullet">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
- 样式中,需要注意的就是所有图片是浮动显示在一行的
<style>
/* reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
/* public */
.clear:after {
content: "";
display: block;
clear: both;
}
.carousel {
position: relative;
width: 480px;
height: 360px;
margin: 20px auto;
overflow: hidden;
}
.items {
position: absolute;
}
.items>li {
float: left;
}
.pre,
.next {
position: absolute;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
color: #fff;
font-size: 30px;
opacity: .8;
}
.pre:hover,
.next:hover {
font-size: 60px;
}
.pre {
left: 10px;
}
.next {
right: 10px;
}
.bullet {
position: absolute;
bottom: 10px;
left: 50%;
transform: translate(-50%);
}
.bullet li {
display: inline-block;
width: 16px;
height: 4px;
background: #fff;
cursor: pointer;
}
.bullet li.active {
background: #666;
}
</style>
- 最后看逻辑部分,需要解释理解的都写在注释里了
<script>
$(function(){
var $pre = $(".pre"),
$next = $(".next"),
$bullet = $(".bullet"),
$items = $(".items"),
$lis = $items.children(),
imgWidth = $lis.width(),
imgCount = $lis.length;
// ul的宽度要能包裹住所有浮动的图片,因此宽度是根据图片宽度和数量计算得出的
$items.css({
left: 0,
width: imgCount * imgWidth
})
var curIdx = 0,
isAnimate = false;
$pre.on('click',function(){
playPre ();
})
$next.on('click',function(){
playNext();
})
$bullet.find('li').on('click',function(){
var idx = $(this).index();
if( curIdx < idx ){
playNext( idx - curIdx );
}else if ( curIdx > idx ){
playPre( curIdx - idx );
}
})
autoPlay();
function playPre(num){
if( isAnimate ) return;
isAnimate = true;
var num = num || 1;
// 需要显示上一张图片时,要先将上一张图片放置ul列表的首位
for( var i=0;i<num;i++){
$items.prepend( $items.children().last() );
}
// 然后设置ul的位置保证当前显示的图片不变
$items.css({ left: 0 - num * imgWidth});
// 再通过animate动态将ul滚至被显示图片的位置,也就是ul首位,所以left:0
$items.animate({ left: 0 },function(){
curIdx = ( curIdx -num +imgCount ) % imgCount;
isAnimate = false;
setBullet();
})
}
function playNext(num){
if( isAnimate ) return;
isAnimate = true;
var num = num || 1;
// 需要显示下一张图片时,先animate将ul整体向左移动一张图片的宽度
// 然后将被移走的图片放置ul的末尾,这里使用for循环的原因就是如果移走的是n张就需要执行n次append方法
$items.animate({ left: '-=' + num * imgWidth },function(){
for( var i=0;i<num;i++ ){
$items.append( $items.children().first() );
}
// 被显示图片位置安排好后,这时候ul已经偏移num * imgWidth了,因此要归0,始终保持被显示图片的位置
$items.css({ left:0 });
// 获取当前被显示图片的下标,并保证下标的取值范围在图片数量以内
curIdx = ( curIdx + num + imgCount ) % imgCount;
isAnimate = false;
setBullet();
})
}
function setBullet(){
$(".bullet").find("li").removeClass("active")
.eq(curIdx).addClass("active");
}
function autoPlay (){
setInterval(function(){
playNext();
},3000)
}
})
</script>
网友评论