轮播图
轮播图是我们在浏览网站的时候很常见的一个部分,比如小米商城,京东商城等等,轮播图可以使网页见面变得非常漂亮,所以学习JS的时候,轮播图是必不缺少的一部分。
轮播原理图
首先有2个盒子,一个轮播盒子,一个大盒子。大盒子每次前进的长度等于轮播盒子的宽度
如图所示
轮播图的实现
html代码如下:
<!-- 轮播图播放窗口 -->
<div class="banner-group" id="banner-group">
<!-- 轮播图火车 -->
<ul class="banner-ul" id="banner-ul">
<li><a href="#"><img src="https://static-image.xfz.cn/1571292192_9.jpg" alt=""></a></li>
<li><a href="#"><img src="https://static-image.xfz.cn/1573180418_322.jpg" alt=""></a></li>
<li><a href="#"><img src="https://static-image.xfz.cn/1573529295_518.jpeg" alt=""></a></li>
<li><a href="#"><img src="https://static-image.xfz.cn/1573529430_855.jpeg" alt=""></a></li>
<li><a href="#"><img src="https://static-image.xfz.cn/1573529430_855.jpeg" alt=""></a></li>
</ul>
<!-- 播放窗口的左右箭头 -->
<span class="arrow left-arrow">‹</span>
<span class="arrow right-arrow">›</span>
<!-- 小圆点 -->
<div class="page-control-group">
<ul class="page-control">
<!-- 由js控制 根据轮播图个数动态生成小圆点 -->
</ul>
</div>
</div>
css部分:
css是用sass语法写的
/* 轮播图播放框 */
.banner-group{
width: $bannerWidth;
height: $bannerHeight;
position: relative;
overflow: hidden;
/* 轮播图火车 */
.banner-ul{
/* width由js动态控制了 */
//width: $bannerWidth*4;
height: $bannerHeight;
position: absolute;
left: 0;
li{
width: $bannerWidth;
height: $bannerHeight;
float: left;
img{
width: 100%;
height: 100%;
}
}
}
/* 轮播图箭头 */
.arrow{
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
color: #fff;
font-size: 70px;
position: absolute;
top: 50%;
margin-top: -40px;
cursor: pointer;
display: none;
}
.left-arrow{
left: 20px;
}
.right-arrow{
right: 20px;
}
/* 轮播图小圆点 */
.page-control-group{
position: absolute;
left: 0;
right: 0;
bottom: 15px;
.page-control{
overflow: hidden;
margin: 0 auto;
cursor: pointer;
/* width由js动态控制了 */
//width: 12px*4 + 8*2px + 16*3px;
li{
width: 12px;
height: 12px;
float: left;
border: 1px solid #fff;
border-radius: 50%;
margin: 0 8px;
box-sizing: border-box;
&.active{
background: #fff;
}
}
js部分
function Banner() {
this.bannerWidth = 798;
this.banner_group = $('#banner-group');
/* index是轮播图切换到第几张的索引 index需要保存
如果不保存当鼠标进入并离开的时候,索引会紊乱 */
this.index = 0;
this.leftArrow = $('.left-arrow');
this.rightArrow = $('.right-arrow');
this.bannerUl = $('#banner-ul');
this.lilist = this.bannerUl.children('li');
this.bannerCount = this.lilist.length;
this.pageControlUl = $('.page-control');
}
/* 轮播图单次跑起来的方法 */
Banner.prototype.animate = function(){
this.bannerUl.animate({'left':-798*this.index},500);
/* 轮播图每跑一次 小圆点也跟着active一次
(轮播图难点) */
this.pageControlUl.children('li').eq(this.index).addClass('active').siblings('li').removeClass('active');
};
/* 轮播图(火车)循环跑起来的方法 */
Banner.prototype.loop = function(){
var self = this;
self.timer = setInterval(function () {
if(self.index>=self.bannerCount-1){
self.index=0;
}else {
self.index+=1;
}
self.animate();
},2000)
};
/* 鼠标悬停事件 */
Banner.prototype.ListenBannerHover = function(){
var self = this;
self.banner_group.hover(function () {
// 相当于鼠标进入事件
clearInterval(self.timer);
self.toggleArrow(true);
},function () {
// 相当与鼠标离开事件
self.loop();
self.toggleArrow(false);
})
};
/* 轮播图箭头的显示与隐藏 */
Banner.prototype.toggleArrow = function(isshow){
if(isshow){
this.leftArrow.show();
this.rightArrow.show();
}else {
this.leftArrow.hide();
this.rightArrow.hide();
}
};
/* 监听轮播图左右箭头点击时间 */
Banner.prototype.ListenArrowClick = function(){
var self = this;
self.leftArrow.click(function () {
if(self.index === 0){
self.index=self.bannerCount-1;
}else {
self.index-=1;
}
self.animate();
});
self.rightArrow.click(function () {
if(self.index === self.bannerCount-1){
self.index=0;
}else {
self.index+=1;
}
self.animate();
});
};
/* 根据轮播图的个数动态的添加小圆点,而不是写死 */
Banner.prototype.initpageControl = function(){
var self = this;
for(var i=0;i<self.bannerCount;i++){
var circle = $('<li></li>');
self.pageControlUl.append(circle);
if(i===0){
circle.addClass('active');
}
}
/* ul的宽度 根据小圆点的个数变化,而不是写死 */
self.pageControlUl.css('width',8*2+12*self.bannerCount+16*(self.bannerCount-1))
};
/* 同理轮播图的火车(ul标签)也不能写死 也要根据轮播图的个数来决定火车的长度 */
Banner.prototype.initBanner = function(){
var self = this;
self.bannerUl.css('width',self.bannerWidth*self.bannerCount);
};
/* 监听小圆点的点击行为 */
Banner.prototype.ListenPageControl = function(){
var self = this;
self.pageControlUl.children('li').each(function (index,obj) {
$(obj).click(function () {
self.index = index;
self.animate();
});
});
};
/* 也可以定义鼠标进入 和鼠标离开的事件
Banner.prototype.ListenMouseEnter = function(){
var self = this;
self.banner_group.mouseenter(function () {
clearInterval(self.timer)
})
};
Banner.prototype.ListenMouseLeave = function(){
var self = this;
self.banner_group.mouseleave(function () {
self.loop();
});
};
*/
Banner.prototype.run = function(){
this.initBanner();
this.initpageControl();
this.loop();
this.ListenArrowClick();
this.ListenBannerHover();
this.ListenPageControl();
};
$(function () {
var banner = new Banner();
banner.run();
});
无限轮播的实现
上面的轮播图有一点美中不足,就是当轮播到最后一张时,切换到第一张的过程中,轮播框快速出现了前面几张轮播图的影子,这样看起来很不爽,下面代码实现了无缝衔接。
无限轮播的原理:如下图,在第3张图的后面又放了第1张的图,这样做的好处就是第3张可以正常的过度到第一张,而不会出现上面的情况。当第3张正常过度到第1张时,利用js快速切换到前面的第1张图上,然后在正常的循环播放。在第1张图的前面放第3张图同理。
不理解要多琢磨琢磨!
function Banner() {
this.bannerWidth = 798;
this.banner_group = $('#banner-group');
/* index是轮播图切换到第几张的索引 index需要保存
如果不保存当鼠标进入并离开的时候,索引会紊乱 */
/* 无限循环播放 index由0改为1 因为在第一张图的停留时间是正常的2倍 */
this.index = 1;
this.leftArrow = $('.left-arrow');
this.rightArrow = $('.right-arrow');
this.bannerUl = $('#banner-ul');
this.lilist = this.bannerUl.children('li');
this.bannerCount = this.lilist.length;
this.pageControlUl = $('.page-control');
}
/* 轮播图单次跑起来的方法 */
Banner.prototype.animate = function(){
var self = this;
self.bannerUl.animate({'left':-798*self.index},500);
/* 轮播图每跑一次 小圆点也跟着active一次
(轮播图难点) */
var index = self.index;
/* 轮播图的索引与小圆点对照
* 轮播图的索引 小圆点的下标
* 0 bannerCount-1
* 1 0
* 2 1
* index index-1
* bannerCount+1 0
* */
if(index===0){
index = self.bannerCount-1;
}else if(index===self.bannerCount+1){
index=0;
}else {
index = self.index-1;
}
self.pageControlUl.children('li').eq(index).addClass('active').siblings('li').removeClass('active');
};
/* 轮播图(火车)循环跑起来的方法 */
Banner.prototype.loop = function(){
var self = this;
self.timer = setInterval(function () {
/* 因为添加了2张图 所以-1 改为+1 */
if(self.index>=self.bannerCount+1){
/* 进到这里说明是最后一张 要立马跳到之前的第一张 */
self.bannerUl.css({'left':-self.bannerWidth});
/* 当前播放是第1张 下一步要播放第2张 由之前0变为2 */
self.index=2;
}else {
self.index+=1;
}
self.animate();
},2000)
};
/* 鼠标悬停事件 */
Banner.prototype.ListenBannerHover = function(){
var self = this;
self.banner_group.hover(function () {
// 相当于鼠标进入事件
clearInterval(self.timer);
self.toggleArrow(true);
},function () {
// 相当与鼠标离开事件
self.loop();
self.toggleArrow(false);
})
};
/* 轮播图箭头的显示与隐藏 */
Banner.prototype.toggleArrow = function(isshow){
if(isshow){
this.leftArrow.show();
this.rightArrow.show();
}else {
this.leftArrow.hide();
this.rightArrow.hide();
}
};
/* 监听轮播图左右箭头点击事件 */
Banner.prototype.ListenArrowClick = function(){
var self = this;
self.leftArrow.click(function () {
if(self.index === 0){
self.bannerUl.css({'left':-self.bannerCount*self.bannerWidth});
self.index=self.bannerCount-1;
}else {
self.index-=1;
}
self.animate();
});
self.rightArrow.click(function () {
/* 实现无限轮播不能-1了,要加1 */
if(self.index === self.bannerCount+1){
self.bannerUl.css({'left':-self.bannerWidth});
self.index=2;
}else {
self.index+=1;
}
self.animate();
});
};
/* 根据轮播图的个数动态的添加小圆点,而不是写死 */
Banner.prototype.initpageControl = function(){
var self = this;
for(var i=0;i<self.bannerCount;i++){
var circle = $('<li></li>');
self.pageControlUl.append(circle);
if(i===0){
circle.addClass('active');
}
}
/* ul的宽度 根据小圆点的个数变化,而不是写死 */
self.pageControlUl.css('width',8*2 + 12*self.bannerCount + 16*(self.bannerCount-1))
};
/* 同理轮播图的火车(ul标签)也不能写死 也要根据轮播图的个数来决定火车的长度 */
Banner.prototype.initBanner = function(){
var self = this;
/* 无限轮播的实现首先复制2张图,即第1张和最后1张 */
var firstbanner = self.lilist.first().clone();
var lastbanner = self.lilist.last().clone();
/* 在最后和最前添加这2张图 */
self.bannerUl.append(firstbanner);
self.bannerUl.prepend(lastbanner);
/* 因为添加了2张图,所以要修改一下火车的宽度 +2
* 同时位置也发生了改变,因为在最前面添加了一张图,
* 所以现在默认显示的是添加的那一张最后面的图,这不是我们想看到的!
* 所以位置要变成-798,让它变成原来第一张的图!'left':-self.bannerWidth
* */
self.bannerUl.css({'width':self.bannerWidth*(self.bannerCount+2),
'left':-self.bannerWidth});
};
/* 监听小圆点的点击行为 */
Banner.prototype.ListenPageControl = function(){
var self = this;
self.pageControlUl.children('li').each(function (index,obj) {
$(obj).click(function () {
/* 这里也要加1,不然有小bug */
self.index = index+1;
self.animate();
});
});
};
Banner.prototype.run = function(){
this.initBanner();
this.initpageControl();
this.loop();
this.ListenArrowClick();
this.ListenBannerHover();
this.ListenPageControl();
};
$(function () {
var banner = new Banner();
banner.run();
});