目录
1、轮播图是个啥?
随便打开一个网站,七八成的概率都能看到网站上至少有一个轮播的横幅图片,电商和视频类网站则更多。现在网上有很多已经封装好的轮播图功能模块,而且使用性能和展示效果都很好,可以直接拿过来用,这里推荐两个:Bootstrap里的Carousel、Swiper触摸滑动插件。平时也都是需要用就直接找,今天突然听到同学面试被问轮播图怎么用 JavaScript 实现,心里一时陷入了沉思,于是决定抽出时间整理一下。
2、实现轮播图 1.0
先从简单的做起,今天就写一个只具备点击按钮,切换到下一张图片的功能的 1.0 版本,然后再根据其缺点和不足,一个个版本进行改进。话不多说,赶紧上车。
2.1 HTML 代码:这里没加图片,用的颜色区分每一张,如果要添加图片的话可以加到 <li> 标签中。图片的数量也可以改动,如果要多加图片,就多加个 <li> 就可以了,这里先写 4 张图片,分别:红、橙、黄、绿。然后再加两个切换按钮。
<div class="wrap">
<ul class="list">
<li class="item active" style="background-color: red;"></li>
<li class="item" style="background-color: orange;"></li>
<li class="item" style="background-color: yellow;"></li>
<li class="item" style="background-color: green;"></li>
</ul>
<button class="btn" id="goPre"><</button>
<button class="btn" id="goNext">></button>
</div>
2.2 CSS 代码:样式这里说一下,-webkit-transition 搭配 opacity 属性实现淡入淡出的效果。还有自定义的 .active 类名,后面会通过 JavaScript 将 <li> 标签设置上 .active 类名,让需要展示的图片浮在几幅图的上方,这里默认先显示第一张(给第一张添加的 .active)。
<style type="text/css">
*{margin: 0;padding: 0;}
.wrap{width: 650px;height: 240px;position: relative;}
.list{list-style: none;position: relative;}
.item{width: 650px;height: 240px;position: absolute;opacity: 0;-webkit-transition: all 2s;}
.btn{width: 30px;height: 40px;position: absolute;top: 100px;z-index: 3;}
#goPre{left: 0;}
#goNext{right: 0;}
.item.active{z-index: 2;opacity: 1;}
</style>
2.3 JavaScript 代码:在 .active 类名的基础上操作,要显示哪一张图片就给哪一张图片加上 .active 类名。
<script type="text/javascript">
window.onload = function(){
var items = document.getElementsByClassName('item');
var goPreBtn = document.getElementById('goPre');
var goNextBtn = document.getElementById('goNext');
var index = 0;//定义index 表示第几张图片在展示 - 表示第几张图片有active类名
function clearActive(){ //展示下一张之前先将所有图片的active类名取消掉
for (var i=0;i<items.length;i++) {
items[i].classList.remove("active");
}
}
function goIndex(){ //将要展示的图片添加上active类名
clearActive(); //调用上面的clearActive()方法,取消所有图片的active类名
items[index].classList.add("active");
}
goNextBtn.onclick = function(){ //给下一张按钮添加鼠标点击事件
if(index < 3) //一共四张图片,next到第五张的时候,将index归零,显示第一张图片
index ++;
else
index = 0;
goIndex(); //调用 goIndex()方法,切换到指定图片
}
goPreBtn.onclick = function(){ //给上一张按钮添加鼠标点击事件
if(index == 0) //一共四张图片,pre到第1张的时候,将index归3,显示最后一张图片
index = 3;
else
index--;
goIndex(); //调用 goIndex()方法,切换到指定图片
}
}
</script>
2.4 效果图
2.5 性能分析
当前这一版本只是简单实现了点击切换图片的功能,勉强可以被称作为轮播图,但是一般轮播图都会在下方有指示器(小圆点,可以表示当前正在显示第几幅图片)。针对这一问题,我们在 2.0 版本对其进行改进。
3、实现轮播图 2.0
1.0 版本实现了轮播图的点击按钮切换图片的基本功能,但是仅有这一功能还算不上真正意义的轮播图。一般的轮播图在图片的下方会有小圆点指示器,可以显示当前正在展示第几幅图片,2.0 版本就将指示器功能实现。
3.1 HTML 代码:在1.0 版本的基础上,添加了指示器结构:pointlist ,并给每个 <li> 添加了 data-index 属性,方便后面操作。
<div class="wrap">
<ul class="list">
<li class="item active" style="background-color: red;"></li>
<li class="item" style="background-color: orange;"></li>
<li class="item" style="background-color: yellow;"></li>
<li class="item" style="background-color: green;"></li>
</ul>
<ul class="pointlist">
<li class="point active" data-index='0'></li>
<li class="point" data-index='1'></li>
<li class="point" data-index='2'></li>
<li class="point" data-index='3'></li>
</ul>
<button class="btn" id="goPre"><</button>
<button class="btn" id="goNext">></button>
</div>
3.2 CSS 代码:在 1.0 版本的基础上,给添加的指示器设置了样式,并自定义的 .active 类名。后面会通过 JavaScript 将 <li> 标签设置上 .active 类名,让当前显示的图片对用的指示器高亮,这里默认先显示第一张(给第一个指示器添加的 .active)。
<style type="text/css">
*{margin: 0;padding: 0;}
.wrap{width: 650px;height: 240px;position: relative;}
.list{list-style: none;position: relative;}
.item{width: 650px;height: 240px;position: absolute;opacity: 0;-webkit-transition: all 2s;}
.btn{width: 30px;height: 40px;position: absolute;top: 100px;z-index: 3;}
#goPre{left: 0;}
#goNext{right: 0;}
.item.active{z-index: 2;opacity: 1;}
.pointlist{list-style: none;position: absolute;right: 20px;bottom: 20px;z-index: 3;}
.point{width: 10px;height: 10px;background-color: rgba(0,0,0,0.4);border-radius: 100%;
float: left;margin-left: 10px;cursor: pointer;}
.point.active{background-color: white;}
</style>
3.3 JavaScript 代码:在 1.0 版本的基础上,给指示器添加了点击事件,点击指示器切换到对应图片。
<script type="text/javascript">
window.onload = function(){
var items = document.getElementsByClassName('item');
var points = document.getElementsByClassName('point');//指示器
var goPreBtn = document.getElementById('goPre');
var goNextBtn = document.getElementById('goNext');
var index = 0;//定义index 表示第几张图片在展示 - 表示第几张图片有active类名
//同时也表示第几个指示器在高亮 - 第几个指示器有active类名
function clearActive(){ //展示下一张之前先将所有图片和指示器的active类名取消掉
for (var i=0;i<items.length;i++) {
items[i].classList.remove("active");
points[i].classList.remove("active");
}
}
function goIndex(){ //将要展示的图片和指示器添加上active类名
clearActive(); //调用上面的clearActive()方法,取消所有图片和指示器的active类名
items[index].classList.add("active");
points[index].classList.add("active");
}
goNextBtn.onclick = function(){ //给下一张按钮添加鼠标点击事件
if(index < 3)
index ++;
else
index = 0;
goIndex(); //调用 goIndex()方法,切换到指定图片和指示器
}
goPreBtn.onclick = function(){ //给上一张按钮添加鼠标点击事件
if(index == 0)
index = 3;
else
index--;
goIndex(); //调用 goIndex()方法,切换到指定图片和指示器
}
for (var i=0;i<points.length;i++) { //给指示器添加点击事件
points[i].onclick = function(){
var pointIndex = this.getAttribute('data-index');//获取当前指示器的data-index
index = pointIndex; //将当前指示器的data-index 赋值给 index
goIndex(); //调用 goIndex()方法,切换到指定的 index 图片和指示器
}
}
}
</script>
3.4 效果图
3.5 性能分析
当前这一版本已经实现了点击切换图片、显示指示器的功能,可以被称作为轮播图,但是,一般的轮播图都有自动轮播的功能(即不用点击切换按钮,图片会自动的切换,方便用户浏览)。针对这一问题,我们在 3.0 版本 对其进行改进。
4、实现轮播图 3.0
2.0 版本已经实现了点击切换图片、显示指示器的功能,可以被称作为轮播图,但是,一般的轮播图都有自动轮播的功能(即不用点击切换按钮,图片会自动的切换,方便用户浏览),今天这一版本就将自动轮播功能实现。
4.1 HTML 代码:实现自动轮播功能不需要改动 HTML 代码,所以这里与 2.0 版本的代码没有区别。
4.2 CSS 代码:实现自动轮播功能不需要改动 CSS 代码,所以这里与 2.0 版本的代码没有区别。
4.3 JavaScript 代码:在 2.0 版本的基础上,添加定时器:setInterval 函数,实现图片的自动轮播。
<script type="text/javascript">
window.onload = function(){
var items = document.getElementsByClassName('item');
var points = document.getElementsByClassName('point');//点
var goPreBtn = document.getElementById('goPre');
var goNextBtn = document.getElementById('goNext');
var index = 0;//index 表示第几张图片在展示,表示第几张图片有active类名
//同时也表示第几个指示器在高亮 - 第几个指示器有active类名
function clearActive(){ //展示下一张之前先将所有图片和指示器的active类名取消掉
for (var i=0;i<items.length;i++) {
items[i].classList.remove("active");
points[i].classList.remove("active");
}
}
function goIndex(){ //将要展示的图片和指示器添加上active类名
clearActive(); //调用上面的clearActive()方法,取消所有图片和指示器的active类名
items[index].classList.add("active");
points[index].classList.add("active");
}
function goNext(){ //定义切换到下一张的函数
if(index < 3)
index ++;
else
index = 0;
goIndex();
}
function goPre(){ //定义切换到上一张的函数
if(index == 0)
index = 3;
else
index--;
goIndex();
}
goNextBtn.onclick = function(){ //给下一张按钮添加鼠标点击事件
goNext();
}
goPreBtn.onclick = function(){ //给上一张按钮添加鼠标点击事件
goPre();
}
for (var i=0;i<points.length;i++) { //给指示器添加点击事件
points[i].onclick = function(){
var pointIndex = this.getAttribute('data-index');//获取当前指示器的data-index
index = pointIndex; //将当前指示器的data-index 赋值给 index
goIndex(); //调用 goIndex()方法,切换到指定的 index 图片和指示器
}
}
setInterval(function(){ //设置定时器
goNext(); //调用goNext()函数,实现自动轮播
},1000)
}
</script>
4.4 效果图
4.5 性能分析
当前这一版本已经实现了点击切换图片、显示指示器和自动轮播的功能,轮播图大体的特征都具备了,但是,这里的定时器存在一个问题,设置的一秒钟切换一张图片,如果中途点击指定图片的话,会在很快切换到下一张,不是重新计时,这样的效果其实并不好。针对这一问题,我们在下一版本对其进行改进。
5、实现轮播图 4.0
上一个版本已经实现了点击切换图片、显示指示器和自动轮播的功能,轮播图大体的特征都具备了,但是,这里的定时器存在一个问题,设置的一秒钟切换一张图片,如果中途点击指定图片的话,会在很快切换到下一张,不是重新计时,这样的体验效果并不好。针对这一问题,我们对其进行改进。
5.1 HTML 代码:实现自动轮播的重新计时功能不需要改动 HTML 代码,所以这里与 3.0 版本的代码没有区别。
5.2 CSS 代码:实现自动轮播的重新计时功能不需要改动 CSS 代码,所以这里与 3.0 版本的代码没有区别。
5.3 JavaScript 代码:在上一个版本的基础上,添加了 time 变量,用来标志定时器图片跳转参数。
<script type="text/javascript">
window.onload = function(){
var items = document.getElementsByClassName('item');
var points = document.getElementsByClassName('point');//点
var goPreBtn = document.getElementById('goPre');
var goNextBtn = document.getElementById('goNext');
var index = 0;//index 表示第几张图片在展示,表示第几张图片有active类名
//同时也表示第几个指示器在高亮 - 第几个指示器有active类名
function clearActive(){ //展示下一张之前先将所有图片和指示器的active类名取消掉
for (var i=0;i<items.length;i++) {
items[i].classList.remove("active");
points[i].classList.remove("active");
}
}
function goIndex(){ //将要展示的图片和指示器添加上active类名
clearActive(); //调用上面的clearActive()方法,取消所有图片和指示器的active类名
items[index].classList.add("active");
points[index].classList.add("active");
}
function goNext(){ //定义切换到下一张的函数
if(index < 3)
index ++;
else
index = 0;
goIndex();
time = 0; //切换图片后令 time = 0
}
function goPre(){ //定义切换到上一张的函数
if(index == 0)
index = 3;
else
index--;
goIndex();
time = 0; //切换图片后令 time = 0
}
goNextBtn.onclick = function(){ //给下一张按钮添加鼠标点击事件
goNext();
}
goPreBtn.onclick = function(){ //给上一张按钮添加鼠标点击事件
goPre();
}
for (var i=0;i<points.length;i++) { //给指示器添加点击事件
points[i].onclick = function(){
var pointIndex = this.getAttribute('data-index');//获取当前指示器的data-index
index = pointIndex; //将当前指示器的data-index 赋值给 index
goIndex(); //调用 goIndex()方法,切换到指定的 index 图片和指示器
time = 0; //每次点击指示器令 time = 0
}
}
var time = 0; //定时器图片跳转参数
setInterval(function(){ //设置定时器
time++;
if(time == 20){
goNext(); //调用goNext()函数,实现自动轮播
time = 0;
}
},100)
}
</script>
5.4 效果图
5.5 性能分析
轮播图的全部功能基本实现了,这种轮播方式是淡入淡出式的,还有一种无缝滑动轮播方式,有时间搞它一下