做项目的时候刚好要做轮播图,之前在微信小程序上做过,但是那个非常的简单,因为很多功能已经封装在了API里面,所以只需要指定几张图片就能达成效果。现在将使用JQuery来实现轮播图效果。

轮播图技术实现

轮播图效果

轮播图下方有每个图的按钮,鼠标放在上面即会跳转到相应页面,而且当鼠标停留在图片上的时候,轮播图将会暂停,以便当用户被某个图片吸引时不至于跳到另一张图片。

原理

轮播图就是将所有的图片使用float来将所有的图片都放成一行上,然后通过js控制图片的移动,原理图如下:

然后还有一处要注意的地方,就是当移动到最后一张图的时候,为了让其依然向左拉动,必须在最后加上复制的第一张图,使之连贯,动画结束后重新定位到起点,然后将最后一张删去

代码部分

html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="banner-wrapper">
<!-- banner图像 -->
<div class="banner-focus">
<ul>
<li><a href="#"><div class="banner-img banner-img0"></div></a></li>
<li><a href="#"><div class="banner-img banner-img1"></div></a></li>
<li><a href="#"><div class="banner-img banner-img2"></div></a></li>
<li><a href="#"><div class="banner-img banner-img3"></div></a></li>
</ul>
</div>

<!-- banner切换按钮 -->
<div class="banner-btn">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>

这里图片并没有采用img标签,而是选择了div标签,然后使用background属性的url指定图片地址,这种方法的好处是不用指定图片的大小,通过设置background-size可以让图片达到充满目标而且多余的部分不显示。因此以后尽量不要使用img标签。应该根据实际情况选择,当图片不是内容的一部分时使用background

less代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
.banner-wrapper {
/*轮播图*/
padding-top: 80px;
height: 550px;
// background-color: #DB6A6A;
position: relative;

.banner-focus {
height: 550px;
width: 100%;
// background-color: #351818;
overflow: hidden;
position: relative;

ul {
position: absolute;
width: 100%;

li {
float: left;
width: 100%;
height: 550px;
list-style: none;

.banner-img {
width: 100%;
height: 550px;
}

.banner-img0 {
/*后面改路径*/
background: url("./test/images/0.jpg") no-repeat center;
background-size: 100%;
}

.banner-img1 {
/*后面改路径*/
background: url("./test/images/1.jpg") no-repeat center;
background-size: 100%;
}

.banner-img2 {
/*后面改路径*/
background: url("./test/images/2.jpg") no-repeat center;
background-size: 100%;
}

.banner-img3 {
/*后面改路径*/
background: url("./test/images/3.jpg") no-repeat center;
background-size: 100%;
}

}
}

}

.banner-btn {
position: absolute;
bottom: 30px;
left: 50%;
margin-left: -52px;

span {
// position: absolute;
float: left;
width: 6px;
height: 6px;
background-color: #E0DFE0;
border-radius: 50%;
margin-right: 20px;
cursor: pointer;

&:hover {
background-color: #595959;
}
}
}
}

css部分需要注意的是

  • 最外层banner-wrapper用position:relative来给内层banner-focus的position:absolute定位

  • banner-focus需要使用overflow:relative来将多余的部分隐藏

  • 若想将内层元素用width百分比来表示,必须指定其父元素宽度才能成功

  • 设置background来让其自动填充,省去了切图的麻烦

js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//============================轮播图部分函数=====================
/*轮播图主函数*/
var bannerRolling = function() {
var sWidth = $(".banner-focus").width(); //获取焦点图的宽度(显示面积)
var len = $(".banner-focus ul li").length; //获取焦点图个数
var index = 0;
var picTimer;

console.log(sWidth);
console.log(len);

//为小按钮添加鼠标滑入事件,以显示相应的内容
$(".banner-btn span").mouseenter(function() {
index = $(".banner-btn span").index(this);
showPics(index, sWidth);
console.log(index, sWidth);
// console.log("按钮滑入");
});

/*
本例为左右滚动,即所有li元素都是在同一排向左浮动,
所以这里需要计算出外围ul元素的宽度
*/
$(".banner-focus ul").css("width",sWidth * (len+1));

/*
因为图片未设置固定宽度,所以之前设置的100%会随着父元素变宽而撑大,
所以此处应该相应设置为父元素的1/(len+1)
*/
$(".banner-focus ul li").css("width",sWidth * (len+1) / 5);


/*直接自动播放*/
picTimer = setInterval(function() {
if(index === len) { //如果索引值等于li元素个数,说明最后一张图播放完毕,接下来要显示第一张图,即调用showFirPic(),然后将索引值清零
index = 0;
showFirstPic(len, sWidth);
} else { //如果索引值不等于li元素个数,按普通状态切换,调用showPics()
showPics(index, sWidth);
}
index++;
},4000); //此2000代表自动播放的间隔,单位:毫秒

//鼠标滑上焦点图时停止自动播放,滑出时开始自动播放
$(".banner-focus").hover(function() {
clearInterval(picTimer);
},function() {
picTimer = setInterval(function() {
if(index === len) { //如果索引值等于li元素个数,说明最后一张图播放完毕,接下来要显示第一张图,即调用showFirPic(),然后将索引值清零
index = 0;
showFirstPic(len, sWidth);
} else { //如果索引值不等于li元素个数,按普通状态切换,调用showPics()
showPics(index, sWidth);
}
index++;
},4000); //此2000代表自动播放的间隔,单位:毫秒
});

}


//显示图片函数,根据接收的index值显示相应的内容
function showPics(index, sWidth) { //普通切换
var nowLeft = - (index * sWidth); //根据index值计算ul元素的left值
$(".banner-focus ul").stop(true,false).animate({"left":nowLeft},500); //通过animate()调整ul元素滚动到计算出的position
// $("#focus div.btn span").animate({"opacity":"0.4"},300).eq(index).animate({"opacity":"1"},100); //为当前的按钮切换到选中的效果
}

//最后一张图自动切换到第一张图时专用
function showFirstPic(len, sWidth) {
$(".banner-focus ul").append($(".banner-focus ul li:first").clone());//为了达到从最右边到最左边还是往左移动效果,而不是往右移动
var nowLeft = - (len * sWidth); //通过li元素个数计算ul元素的left值,也就是最后一个li元素的右边
$(".banner-focus ul").stop(true,false).animate({"left":nowLeft},500,function() {
//通过callback,在动画结束后把ul元素重新定位到起点,然后删除最后一个复制过去的元素
$(".banner-focus ul").css("left","0");
$(".banner-focus ul li:last").remove();
});
// $("#focus div.btn span").animate({"opacity":"0.4"},300).eq(index).animate({"opacity":"1"},100); //为当前的按钮切换到选中的效果
}
  • setInterval()函数用来不断调用内容,为了让一开始轮播图自动滚动,要直接用setInterval函数然后实现鼠标聚焦内容的时候停止滚动,使之hover用clearInterval使其停止,然后用callback回调函数继续滚动

  • 滚动原理是通过position:absolute然后使用left来指定展示哪一张图片

  • 由于我并没有指定图像大小,所以我在此处设置了图像宽度为width:100%来自动调整,那么此时li的父元素ul会是所有图片宽度之和,根据width:100%会参照其父元素的原因,我在此处指定了li的宽度,为ul宽度的1/(len+1),len+1是因为会复制一张图片

后记

还有一种轮播图是用纯CSS效果写的,目前还没有细读代码,纯css的局限性是似乎不能指定显示哪一张图片,而是让其自动滚动。