- 该插件由轮播图片、向前向后按钮及底部分页器3部分组成
- 逻辑上不操作
dom
,在原有图片列表的首尾分别clone
列表最后一项和第一项
- 图解下基本逻辑:
- 如下图所示,图片列表共有4张图片,分别在列表首尾
clone
最后一张和第一张图
- 先说
next
按钮,点击该按钮,图片列表向左移动,当移动到图片4时,点击next
列表继续向左移动显示
clone1
,这时修改列表left
属性值到图片1的位置,此时用户看到的显示的图片并没有改变,后面列表就
可以继续向左移动了
-
pre
按钮则与之相反,点击该按钮,列表向右移动,当移动到图片1时,点击pre
列表继续向右移动一格,
此时同样修改列表left
属性,让列表移动到图片4的位置
carousel-nodom-diagram.PNG
- 下面看代码,
Dom
结构很简单,<a href="javascript:void(0)">
表示不让a
跳转
<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>
- 逻辑部分主要为
pre
next
按钮功能,我们将所有函数写在一个立即执行函数里
$(function(){
var $pre = $(".pre"),
$next = $(".next"),
$bullet = $(".bullet"),
$items = $(".items"),
$lis = $items.children(),
imgWidth = $lis.width(),
imgCount = $lis.length; //初始图片的数量,在这里为4
})
// 分别在列表首尾clone列表最后一项和第一项
$lis.last().clone().prependTo($items);
$lis.first().clone().appendTo($items);
// 再获取现在的图片数量,应该是imgCount+2,现在为6
imgRealCount = $items.children().length;
// 此时列表第一项其实是clone1,因此要将ul左移一张图片的距离,保证显示原有的第一项(图片1)
$items.css({
left: 0 - imgWidth,
width: imgWidth * imgRealCount
})
// 设置轮播初始图片下标和防止重复点击重复执行滚动
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 playNext(num){
if( isAnimate ) return;
isAnimate = true;
// 默认滚动一张图片
var num = num || 1;
// next一直执行ul向左移的动画
$items.animate({ left: '-=' + num * imgWidth },function(){
// 通过当前展示图片的下标和滚动数量计算出需要滚动到的图片的下标
// 这里的curIdx取值范围始终小于imgCount,也就是取值在0-3之间
curIdx = ( curIdx + num ) % imgCount;
// 如果curIdx == 0,就表示滚动到了图片clone1
// 这时再将ul列表的位置设置到图片1
if( curIdx == 0 ) {
$items.css({ left: 0 - imgWidth });
}
isAnimate = false;
setBullet();
})
}
function playPre(num){
if( isAnimate ) return;
isAnimate = true;
// 默认滚动一张图片
var num = num || 1;
// pre一直执行ul向右移的动画
$items.animate({ left: '+=' + num * imgWidth },function(){
curIdx = ( curIdx -num +imgCount ) % imgCount;
// 通过计算,如果下一张展示的图片是clone4
// 这时将ul列表位置设置为图片4
if( curIdx == imgCount - 1 ){
$items.css({ left: 0 - imgCount * imgWidth });
}
isAnimate = false;
setBullet();
})
}
- 最后实现分页器点击时的样式效果和
autoPlay()
function setBullet(){
// 获取当前被点击的元素下标,添加class
$bullet.find('li').removeClass('active')
.eq(curIdx).addClass('active');
}
function autoPlay(){
setInterval(function(){
playNext();
},3000)
}