演示效果:
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--CSS样式布局-->
<style>
*{/*偷懒的方法,开发中最好不要用这个通配符*/
margin: 0;
padding: 0;
}
#box{
width:500px;
height:200px;
border:1px solid #000;
padding:5px;
margin:100px auto;
}
.inner {
width: 500px;
height: 200px;
position: relative;
overflow:hidden;
}
ul {
width: 600%;
height: 200px;
list-style: none;
position: absolute;
}
ul>li{
width: 500px;
float:left;
}
ol{
list-style-type:none;
position: absolute;
right: 30px;
bottom: 15px;
}
ol>li {
width: 20px;
height: 20px;
background-color: white;
border-radius: 50%;
margin-left: 15px;
float: left;
line-height: 20px;
text-align: center;
cursor:pointer;
}
.current{
color:white;
background-color: orange;
}
.switchBtn{
display: none;
}
.switchBtn>span{
width: 30px;
height: 60px;
line-height: 60px;
text-align: center;
position: absolute;
background-color: rgba(0, 0, 0, 0.2);
top: 50%;
margin-top: -30px;
font-size:40px;
color:white;
}
.switchBtn>span:last-child{
right:0;
}
</style>
</head>
<body>
<!--HTML页面布局-->
<div id="box">
<div class="inner">
<ul>
<li><img src="image/1.jpg" alt=""></li>
<li><img src="image/2.jpg" alt=""></li>
<li><img src="image/3.jpg" alt=""></li>
<li><img src="image/4.jpg" alt=""></li>
<li><img src="image/5.jpg" alt=""></li>
</ul>
<ol>
<li class="current">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
<div class="switchBtn">
<span><</span>
<span>></span>
</div>
</div>
</div>
<script>
/*需求: 无缝轮播 左右切换 焦点图(也就是小圆点)
步骤:
1.获取元素 box ul ol oLiArr switch-button spanArr
2.克隆第一个uli 拼接到ul最后
3.鼠标移入移出box 显示与隐藏 切换按钮
4.启动定时器 索引值++ 自动位移ul进行自动轮播
5.定时器内 针对索引最大值判断 匀速加闪动 实现无缝轮播
6.焦点图实现
7.左右滑动图实现
8.把焦点图的索引值和左右切换图的索引值 和无缝轮播的索引值保持一致*/
//获取页面要要用到的元素
var box = document.getElementById("box");
var ul=document.getElementsByTagName("ul")[0];
var moveWidth=ul.children[0].offsetWidth;
var ol=document.getElementsByTagName("ol")[0];
var oliArr=ol.children;
var switchBtn=document.getElementsByClassName("switchBtn")[0];
var spanArr=switchBtn.children;
//声明图片的角标,并记录
var index=0;
//声明小圆点的角标,并记录
var circleIndex=0;
//把ul下的第一个子元素的克隆到最后一个(为了实现无缝轮播的效果)
ul.appendChild(ul.children[0].cloneNode(true));
//添加鼠标移入事件
box.onmouseover=function () {
//使鼠标移入时显示左右两边的切换按钮
switchBtn.style.display="block";
//并停止定时器,定制自动轮播效果
clearInterval(timer);
}
//添加鼠标移出事件
box.onmouseout=function () {
//使鼠标移出时隐藏左右两边的切换按钮
switchBtn.style.display="none";
//并启动定时器,启动自动轮播
timer=setInterval(autoPlay,2000);
}
//声明定义变量接收定时器,用于清除定时器时使用
var timer=setInterval(autoPlay,2000);
//自动播放方法封装
function autoPlay(){
//每次执行次函数,图片角标自+1,为了实现自动播放效果
index++;
//if判断当图片的角标大于所有图片的个数时,无缝衔接到第一张,再次进行轮播效果
if(index>ul.children.length-1){
ul.style.left=0;
index=1;
}
//使其每个图片轮播都是匀速的
yunsuX(ul,-index*moveWidth);
//每次执行次函数,小圆点角标自+1,为了跟随图片滚动
circleIndex++;
//判断小圆点的小标大于整个小圆点的格式时,使其回到第一位,再次轮播
if(circleIndex>oliArr.length-1){
circleIndex=0;
}
//排他思想
//先for循环遍历,每一个小圆点
for(var i=0;i<oliArr.length;i++){
//先干掉所有人包括自己
oliArr[i].removeAttribute("class");
}
//然后在复活自己,使自己有颜色字体的变化(css样式控制的)
oliArr[circleIndex].setAttribute("class","current");
}
//焦点图(小圆点)点击切换到对应的图片
//循环遍历为每一个小圆点添加绑定事件
for(var i=0;i<oliArr.length;i++){
//想绑定每一个小圆点的角标
oliArr[i].index=i;
//为小圆点添加鼠标点击事件
oliArr[i].onclick= function () {
//循环遍历每一个小圆点,利用排他思想
for(var i=0;i<oliArr.length;i++){
//先干掉所有人,包括自己
oliArr[i].removeAttribute("class");
}
//在复活自己(this指谁调用的该事件this表示的就是谁)
this.setAttribute("class","current");
//匀速动画调用,使用匀速动画到和小圆点对应的位置
yunsuX(ul,-this.index*moveWidth);
//绑定图片角标和小圆点的小标,使其角标一样绑定
index=circleIndex=this.index;
}
}
//左右按钮切换图片
//左侧按钮切换图片
spanArr[0].onclick=function(){
//因为正常的轮播是由由右向左滑动的,左边的按钮是由左向右滑动的
//所以图片角标为--
index--;
//if判断,向左滑动时到达第一张图片,无缝衔接到最后一张图片
if(index<0){
ul.style.left=-(ul.children.length-1)*moveWidth+"px";
index=ul.children.length-2;
}
//执行匀速动画,使其切换时时匀速的效果
yunsuX(ul,-index*moveWidth);
//小圆点与图片角标同理,因为相反的方向所以是--
circleIndex--;
//为了解决轮播图从第五张图片切换到第一张时,通过小圆点点击第二张会出现图片倒着回到第一张
//在轮播第二张的bug问题(也是现在淘宝轮播图未解决的问题)
if(circleIndex<0){
circleIndex=oliArr.length-1;
}
//循环遍历,是每个小圆点都与图片保持一致
for(var i=0;i<oliArr.length;i++){
oliArr[i].removeAttribute("class");
}
oliArr[circleIndex].setAttribute("class","current");
}
//右侧按钮切换图片
//因为右侧切换时正续,所以直接执行封装好的自动播放代码即可
spanArr[1].onclick=function(){
autoPlay();
};
//匀速动画的封装
function yunsuX(ele,endX){
//1.要用定时器先清除定时器,(不清楚的话,会出现多个定时器的累加,会带来很不好的影响)
clearInterval(ele.timer);
//2.定义步长,通过if判断获取步长的正负值,
var step;
if(endX-ele.offsetLeft>0){
//endX-ele.offsetLeft>0,终点位置减当前位置大于0,表示还未到终点位置,所以步长为正值
step=10;
}else if(endX-ele.offsetLeft<0){
//endX-ele.offsetLeft<0,终点位置减当前位置小于0,表示已到达终点位置,所以步长为负值
//使其可以再回到起点位置
step=-10;
}else{
//当上边条件都不满足是表示endX-ele.offsetLeft=0,表示已到达终点,步长为0,不动
step=0;
}
//3.启动定时器
ele.timer=setInterval(function () {
//4.位移元素位置,使其匀速运动
ele.style.left=ele.offsetLeft+step+"px";
//5判断停止定时器
if(Math.abs(endX-ele.offsetLeft)<Math.abs(step)){
//当距离终点距离小于一步长是停止定时器
clearInterval(ele.timer);
//把盒子位置直接拉到终点的位置
ele.style.left=endX+"px";
}
},10)
}
</script>
</body>
</html>
图片资源: