本文详细讲解如何使用原生JavaScript实现从左向右滑动的轮播图效果。通过HTML结构布局、CSS绝对定位与溢出隐藏,以及JS中利用setTimeout实现的平滑移动算法,完整展示图片自动播放、小圆点切换及无缝衔接的实现原理与代码细节。
轮播图效果概述
轮播图是一种让图片每隔几秒自动滑动,从而实现图片轮流播放的组件。从视觉效果来看,轮播图主要分为滑动式和渐入式两种。滑动式轮播图表现为图片从左向右滑入的动画效果,而渐入式则是通过透明度变化逐渐显示图片。本文重点介绍第一种滑动式效果的实现方法。
实现原理
原理
核心思路是将相同大小的图片排列成一列,但在视口中仅显示其中一张,其余图片隐藏。通过动态修改容器的left属性值,来切换当前显示的图片。

点击查看效果
HTML结构布局
html部分
HTML结构中,nav作为总容器。第一个ul列表#index用于存放小圆点指示器,鼠标悬停在哪个小圆点上,就显示对应的第几张图片,其中on类用于给当前选中的小圆点添加背景颜色。第二个ul列表#img用于存放图片列表。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Carousel Figure</title>
<link rel="stylesheet" href="style.css" >
</head>
<body>
<!--从左向右滑动-->
<nav>
<ul id="index">
<li class="on"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul id="img">
<li><img src="../images/img1.jpg" alt="img1"></li>
<li><img src="../images/img2.jpg" alt="img2"></li>
<li><img src="../images/img3.jpg" alt="img3"></li>
<li><img src="../images/img4.jpg" alt="img4"></li>
<li><img src="../images/img5.jpg" alt="img5"></li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
CSS样式设置
css部分
所有图片的尺寸均设定为720*405像素。在CSS样式设置中,需要注意以下几个关键点:
图片列表#img相对于总容器nav采用绝对定位。#img的宽度必须设置为所有图片宽度的总和,这样才能使图片并列排成一行显示。
总容器nav的宽度必须严格设置为图片的宽度720px,这意味着视口只能显示一张图片。对于超出容器宽度的部分,需设置overflow: hidden进行隐藏。
小圆点列表需要显示在图片列表的上方,因此需将#img的z-index设置为-1,以确保小圆点层级高于图片层。
小圆点列表由一系列li元素通过改变边框样式构成。实现移动小圆点效果只需动态改变背景颜色即可。
*{
margin:0;
padding:0;
}
nav{
width: 720px;
height: 405px;
margin:20px auto;
overflow: hidden;
position: relative;
}
#index{
position: absolute;
left:320px;
bottom: 20px;
}
#index li{
width:8px;
height: 8px;
border: solid 1px gray;
border-radius: 100%;
background-color: #eee;
display: inline-block;
}
#img{
width: 3600px;/*不给宽高无法移动*/
height: 405px;
position: absolute;/*不定义absolute,js无法设置left和top*/
z-index: -1;
}
#img li{
width: 720px;
height: 405px;
float: left;
}
#index .on{
background-color: black;
}
JavaScript交互逻辑
JS部分
图片平滑移动函数
图片移动函数moveElement()
moveElement函数负责获取图片当前的位置以及目标位置,并计算两者之间的差距以执行移动操作。可以使用offsetLeft和offsetTop属性获取图片的当前位置。为了实现图片移动时的“划过”平滑效果,需要将总距离分成10次移动完成,这通过调用setTimeout函数实现。同时,为了防止鼠标悬停时动画继续执行,需要调用clearTimeout()函数清除定时器,具体代码如下:
function moveElement(ele,x_final,y_final,interval){//ele为元素对象
var x_pos=ele.offsetLeft;
var y_pos=ele.offsetTop;
var dist=0;
if(ele.movement){//防止悬停
clearTimeout(ele.movement);
}
if(x_pos==x_final&&y_pos==y_final){//先判断是否需要移动
return;
}
dist=Math.ceil(Math.abs(x_final-x_pos)/10);//分10次移动完成
x_pos = x_pos<x_final ? x_pos+dist : x_pos-dist;
dist=Math.ceil(Math.abs(y_final-y_pos)/10);//分10次移动完成
y_pos = y_pos<y_final ? y_pos+dist : y_pos-dist;
ele.style.left=x_pos+'px';
ele.style.top=y_pos+'px';
ele.movement=setTimeout(function(){//分10次移动,自调用10次
moveElement(ele,x_final,y_final,interval);
},interval)
}
小圆点切换逻辑
小圆点移动函数moveIndex()
移动小圆点的实质是移动设置背景颜色的on类。其原理是先判断哪个li元素上存在背景颜色,如果存在则移除该样式,使所有li元素都失去背景色,然后为当前选中的li元素重新添加on背景样式。
function moveIndex(list,num){//移动小圆点
for(var i=0;i<list.length;i++){
if(list[i].className=='on'){//清除li的背景样式
list[i].className='';
}
}
list[num].className='on';
}
自动轮播功能
图片自动轮播
将以下代码直接写在window.onload事件中即可。这里需要定义一个变量index,用于表示当前移动到第index张图片(索引范围0~n-1,其中n为li的总个数)。
var img=document.getElementById('img');
var list=document.getElementById('index').getElementsByTagName('li');
var index=0;//这里定义index是变量,不是属性
var nextMove=function(){//一直向右移动,最后一个之后返回
index+=1;
if(index>=list.length){
index=0;
}
moveIndex(list,index);
moveElement(img,-720*index,0,20);
};
图片的自动轮播功能依赖于setInterval()函数,该函数让程序每隔几秒自动调用nextMove()函数,具体代码如下:
var play=function(){
timer=setInterval(function(){
nextMove();
},2500);
};
鼠标交互效果
鼠标覆盖小圆点效果
要实现鼠标覆盖哪个小圆点就呈现对应图片的效果,需要识别鼠标当前覆盖的是哪个小圆点。为此,给每个li元素添加一个自定义属性index,使其值等于对应小圆点的序号i(范围0~n-1,n为li的总个数)。这样在每次鼠标覆盖事件中,只需获取该index属性的值即可知道当前操作的是哪个小圆点。需要注意的是,这个自定义属性index与JavaScript变量index没有任何关系,仅仅是名称相同。
for(var i=0;i<list.length;i++){//鼠标覆盖上哪个小圆圈,图片就移动到哪个小圆圈,并停止
list[i].index=i;//这里是设置index属性,和index变量没有任何联系
list[i].onmouseover= function () {
var clickIndex=parseInt(this.index);
moveElement(img,-720*clickIndex,0,20);
index=clickIndex;
moveIndex(list,index);
clearInterval(timer);
};
list[i].onmouseout= function () {//移开后继续轮播
play();
};
}
无缝衔接优化与总结
总结
轮播图的实现并不复杂,关键在于将图片的移动行为和小圆点的移动行为分离处理,这样逻辑更加清晰。不过,这个轮播图实现仍存在一个小问题:从最后一幅图滑向第一幅时,滑动的距离较长。这个问题其实很容易解决,只需调整滑动计算方式即可。目前的实现是根据-720*index来计算最终的left值,且index将图片的移动和小圆点的移动绑定在一起。如果将滑动方式改为基于当前的offsetLeft加上(-720),图片的移动就可以与index值解耦。为此,需要在HTML文件中增加一幅额外的图片:
<li><img src="../images/img1.jpg" alt="img1"></li>
<li><img src="../images/img2.jpg" alt="img2"></li>
<li><img src="../images/img3.jpg" alt="img3"></li>
<li><img src="../images/img4.jpg" alt="img4"></li>
<li><img src="../images/img5.jpg" alt="img5"></li>
<li><img src="../images/img1.jpg" alt="img1"></li>
然后在滑到最后一幅图片时,迅速将偏移量赋值为0,使其变为第一幅图的状态。由于这两幅图片内容相同,用户无法分辨其中的变化,从而达到了无缝连接的效果。
if(x_pos==-3600){
ele.style.left='0';
ele.style.top='0';
}else{
ele.style.left=x_pos+'px';
ele.style.top=y_pos+'px';
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。