持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
前言
大家可能都有通过ui库实现轮播图的经历,本文将通过原生JS的方式来实现,让大家能够更为清楚其实现的原理与要点。
步骤流程
在实现之前,我们先来大概 描述一下轮播图实现的流程。
1.首先我们肯定得有轮播图的展示区展示轮播的图片
2.轮播的图片一般是一个ul无序列表我们将其宽度设置为总图片宽度+左右外边距margin。轮播图展示区position属性设置为relative,再将ul列表展示区position属性设为absolute就能够通过设置left值使其向左滚动。
3.在图片上还应该有a标签(阻止跳转事件)或者li标签充当跳转按钮,再循环遍历这些按钮绑定跳转事件控制left值大小移动来指定图片即可,可通过定时器来控制移动的动画效果。
4.幻灯片播放与跳转类似,只是图片展示和按钮展示要一致。并且在自动播放时若点击了跳转按钮,应该清除自动播放的定时器停止播放,防止冲突。再跳转事件结束后再开启自动播放定时器即可。
5.但这样会有一个问题,假设我们自动播放的频率为3s,那我从最后一张播放到第一张left值是不是从(index-1)*width(图片总宽度乘数组长度减去1)到0,肯定是ul总体是得向右到第一张图片给大家演示一下,这样花费时间一般是大于2倍的播放频率
那么,这样就会有冲突,因为这样的话,它可能直接就跳到第二张图片这样。
那么,该如何解决呢?
我们可以在末尾再放第一张图片,然后从最后一张点击跳转到第一张时把left值直接修改为0,他是不是直接就到第一张了,自动播放也可继续进行了。注意!!不可以在点击第五张图片就把left值修改为0,这样点击事件的第五张图片就直接到第一张了,必须在末尾新增第一张图片!!!
ps:不理解的抱歉哈,演示在后续实现中进行,这里不好演示
实现
1.网页结构与css
<div id="carousel">
<ul id="imgList">
<li><img src="./img/1.jpg"></li>
<li><img src="./img/2.jpg"></li>
<li><img src="./img/3.jpg"></li>
<li><img src="./img/4.jpg"></li>
<li><img src="./img/5.jpg"></li>
<li><img src="./img/1.jpg"/></li>
</ul>
<div id="handler">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
<style>
*{
margin: 0;
padding: 0;
}
#carousel{
/*设置轮播图展示区的大小颜色*/
width: 945px;
height: 617px;
margin: 10px auto;
background-color: royalblue;
padding: 20px 0;
/*设置定位成为ul父元素*/
position: relative;
/*裁剪溢出轮播图展示区的图片内容*/
overflow: hidden;
}
#imgList{
list-style: none;
position: absolute;
}
#imgList li{
float: left;
margin: 0 10px;
width: 925px;
height: 617px;
}
#imgList li img{
width:100%;
height:100%;
}
#handler{
/*设置a标签按钮位置*/
position: absolute;
bottom: 40px;
}
#handler a{
/*设置a标签按钮大小样式*/
float: left;
width: 20px;
height: 20px;
background-color: grey;
opacity: 0.6;
margin: 0 10px;
}
#handler a:hover{
/*设置a标签悬浮效果*/
background-color: aquamarine;
}
</style>
2.动态设置轮播图展示区宽度及按钮区的位置
window.onload=function(){
//获取ul列表
var imgList=document.getElementById('imgList');
//获取所有图片标签
var img=document.getElementsByTagName('img')
//动态设置ul的宽度以适应图片的动态增加减少
imgList.style.width=img.length*945+"px";
/*设置导航按钮居中*/
//获取handler轮播图导航栏
var handler = document.getElementById("handler");
//获取carousel的div
var carousel = document.getElementById("carousel");
//设置获取handler的left值,以适应动态的增加减少a标签达到居中效果
handler.style.left = (carousel.offsetWidth - handler.offsetWidth)/2 + "px";
}
3.为按钮绑定事件
//设置图片的索引
var index=0;
//获取所有a标签
var a=document.getElementsByTagName("a");
//选中图片默认样式
a[index].style.backgroundColor="aquamarine";
//为所有的超链接都绑定单击响应函数
for(var i=0; i<a.length ; i++){
//为每一个超链接都添加一个num属性
a[i].num = i;
//为超链接绑定单击响应函数
a[i].onclick = function(){
//关闭自动切换的定时器
clearInterval(timer);
//获取点击超链接的索引,并将其设置为index
index = this.num;
//切换图片
/*
* 第一张 0 0
* 第二张 1 -945
* 第三张 2 -1890
*/
//设置选中的a标签
active();
//使用move函数来切换图片
move(imgList , "left" , -945*index , 45,function(){
//设置自动切换
autoChange();
});
};
4.图片操作函数
function active(){
//判断当前索引是否是最后一张图片
if(index >= img.length - 1){
//则将index设置为0
index = 0;
//此时显示的最后一张图片,而最后一张图片和第一张是一摸一样
//通过CSS将最后一张切换成第一张
imgList.style.left = 0;
}
//遍历所有a,并将它们的背景颜色设置为红色
for(var i=0 ; i<a.length ; i++){
a[i].style.backgroundColor = "";
}
a[index].style.backgroundColor = "aquamarine";
};
function move(obj, direction, target, speed, callback) {
//关闭上一个定时器
clearInterval(obj.timer);
//获取元素目前的位置
var current = parseInt(getComputedStyle(obj,null)[direction]);
//判断速度的正负值
//如果从0 向 target移动,则speed为正
//如果从target向0移动,则speed为负
if(current>target){
speed=-speed;
}
//开启一个定时器,用来执行动画效果
//向执行动画的对象中添加一个timer属性,用来保存它自己的定时器的标识
obj.timer = setInterval(function() {
//获取box1的原来的left值
var oldValue = parseInt(getComputedStyle(obj,null)[direction]);
//在旧值的基础上增加
var newValue = oldValue + speed;
//判断newValue是否大于target
//向左移动时,需要判断newValue是否小于target
//向右移动时,需要判断newValue是否大于target
if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
//将新值设置给box1
obj.style[direction] = newValue + "px";
//当元素移动到0px时,使其停止执行动画
if(newValue == target) {
//达到目标,关闭定时器
clearInterval(obj.timer);
callback && callback();
}
}, 30);
};
//定义一个自动切换的定时器的标识
var timer;
//创建一个函数,用来开启自动切换图片
function autoChange(){
//开启一个定时器,用来定时去切换图片
timer = setInterval(function(){
//使索引自增
index++;
//判断index的值
index %= img.length;
//执行动画,切换图片
move(imgList , "left" , -945*index , 45,function(){
//修改导航按钮
active();
} );
},3000);
};
效果
最后一张自动播放到第一张(取消overflow:hidden让大家看更清楚)
总体效果图
总结
这就是有关原生JS实现轮播图的实现。希望大家能够有所得,有问题的欢迎共同讨论