原生JS与jQuery实现图片淡入淡出轮播效果详解
本文详细讲解如何使用原生JavaScript和jQuery两种方式实现图片轮播的淡入淡出效果。文章首先构建HTML结构与CSS样式,随后分别演示jQuery的fadeIn/fadeOut方法及原生JS模拟实现,涵盖自动播放、鼠标交互及索引控制等核心功能。
图片轮播效果概述与结构构建
图片轮播有多种实现形式,本文重点介绍其中的淡入淡出效果。
无论是使用原生JavaScript还是jQuery均可实现该功能。由于jQuery封装了大量便捷方法,其实现过程相对简单;若使用原生JS,则需手动模拟这些jQuery方法的行为。
无论采用何种技术栈,构建基础的表现层结构都是必不可少的步骤。

一个标准的图片轮播组件通常由以下几个部分构成。
针对淡入淡出式的轮播组件,
1. 首先需要定义最外层的容器(即整体wrapper)。
2. 接着设置图片轮播的主体区域(通常称为banner)。
3. 然后构建图片组,可以使用独立的div,也可以直接使用ul结合li的形式。
4. 随后添加一个半透明背景层,置于图片底部。
5. 接着设置图片描述信息层(info层),位于透明背景层的左下角,可使用div或ul结合li实现。
6. 然后设置按钮层,用于定位图片组的当前索引(index),位于透明背景层的右下角,同样可使用div或ul结合li实现。
7. 此外,有时会在图片两侧添加左右箭头(< 和 >)以指示轮播方向(本文暂不涉及,如需添加,逻辑与此类似)。
基于上述结构,可以构建出相应的HTML代码。
<div class="wrapper"><!-- 最外层部分 -->
<div class="banner"><!-- 轮播部分 -->
<ul class="imgList"><!-- 图片部分 -->
<li class="imgOn"><a href="#"><img src="./img/test1.jpg" width="400px" height="200px" alt="puss in boots1"></a></li>
<li><a href="#"><img src="./img/test2.jpg" width="400px" height="200px" alt="puss in boots2"></a></li>
<li><a href="#"><img src="./img/test3.jpg" width="400px" height="200px" alt="puss in boots3"></a></li>
<li><a href="#"><img src="./img/test4.jpg" width="400px" height="200px" alt="puss in boots4"></a></li>
<li><a href="#"><img src="./img/test5.jpg" width="400px" height="200px" alt="puss in boots5"></a></li>
</ul>
<div class="bg"></div> <!-- 图片底部背景层部分-->
<ul class="infoList"><!-- 图片左下角文字信息部分 -->
<li class="infoOn">puss in boots1</li>
<li>puss in boots2</li>
<li>puss in boots3</li>
<li>puss in boots4</li>
<li>puss in boots5</li>
</ul>
<ul class="indexList"><!-- 图片右下角序号部分 -->
<li class="indexOn">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</div>
图片部分的alt属性对应infoList部分的信息内容,必要时可进行绑定。需要注意的是,imgList中图片的宽度和高度应尽快设定,若在CSS中统一设定可能会导致加载变慢。
此处为三个部分的active状态均添加了对应的on类,实际使用中可能不需要如此多的active状态。
接下来为组件设置CSS样式。
<style type="text/css">
body,div,ul,li,a,img{margin: 0;padding: 0;}
ul,li{list-style: none;}
a{text-decoration: none;}
.wrapper{position: relative;margin: 30px auto;width: 400px;height: 200px;}
.banner{width: 400px;height: 200px;overflow: hidden;}
.imgList{width:400px;height:200px;z-index: 10;}
.imgList li{display: none;}
.imgList .imgOn{display: inline;}
.bg{position: absolute;bottom: 0;width: 400px;height: 40px;z-index:20;opacity: 0.4;filter:alpha(opacity=40);background: black;}
.infoList{position: absolute;left: 10px;bottom: 10px;z-index: 30;}
.infoList li{display: none;}
.infoList .infoOn{display: inline;color: white;}
.indexList{position: absolute;right: 10px;bottom: 5px;z-index: 30;}
.indexList li{float: left;margin-right: 5px;padding: 2px 4px;border: 2px solid black;background: grey;cursor: pointer;}
.indexList .indexOn{background: red;font-weight: bold;color: white;}
</style>
具体说明如下:
1、banner定义了图片轮播的范围,此处设定为宽400像素、高200像素,图片所在的ul外围也采用相同的尺寸设置。
2、为了显示当前激活项,先将所有li设置为display:none,然后为带有on类的li设置display:inline。
3、由于使用jQuery的fadeIn()方法时,元素会变化为display:list-item,因此需要在banner容器上添加overflow:hidden属性,否则在快速切换图片时,整体图片高度可能会超出预设高度。

4、务必为每个部分添加z-index值,以防止元素被覆盖而无法显示。
编写至此,应先检查页面是否正确显示了第一项。若显示正常,再继续添加JavaScript处理逻辑。
jQuery实现淡入淡出轮播
一、jQuery实现方式
1. 定义一个当前图片对应的标号变量:curIndex = 0;。
2. 默认情况下组件会自动轮播,因此默认添加
var autoChange = setInterval(function(){
if(curIndex < $(".imgList li").length-1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
默认使curIndex自增,随后重置为0。
3. 其中changeTo()函数用于执行切换操作。
function changeTo(num){
$(".imgList").find("li").removeClass("imgOn").hide().eq(num).fadeIn().addClass("imgOn");
$(".infoList").find("li").removeClass("infoOn").eq(num).addClass("infoOn");
$(".indexList").find("li").removeClass("indexOn").eq(num).addClass("indexOn");
}
具体逻辑依实际情况而定。
4. 此外,还需处理鼠标滑入和滑出右下角索引按钮时的事件。
$(".indexList").find("li").each(function(item){
$(this).hover(function(){
clearInterval(autoChange);
changeTo(item);
curIndex = item;
},function(){
autoChange = setInterval(function(){
if(curIndex < $(".imgList li").length-1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
});
});
当鼠标滑入时,清除定时器,并执行图片切换处理。随后将curIndex设置为当前item(注意不要遗漏此步骤)。
当鼠标滑出时,重置定时器,恢复默认状态。
至此,淡入淡出效果即告完成。
完整代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>图片轮播 jq(淡入淡出)</title>
<style type="text/css">
body,div,ul,li,a,img{margin: 0;padding: 0;}
ul,li{list-style: none;}
a{text-decoration: none;}
.wrapper{position: relative;margin: 30px auto;width: 400px;height: 200px;}
.banner{width: 400px;height: 200px;overflow: hidden;}
.imgList{width:400px;height:200px;z-index: 10;}
.imgList li{display: none;}
.imgList .imgOn{display: inline;}
.bg{position: absolute;bottom: 0;width: 400px;height: 40px;z-index:20;opacity: 0.4;filter:alpha(opacity=40);background: black;}
.infoList{position: absolute;left: 10px;bottom: 10px;z-index: 30;}
.infoList li{display: none;}
.infoList .infoOn{display: inline;color: white;}
.indexList{position: absolute;right: 10px;bottom: 5px;z-index: 30;}
.indexList li{float: left;margin-right: 5px;padding: 2px 4px;border: 2px solid black;background: grey;cursor: pointer;}
.indexList .indexOn{background: red;font-weight: bold;color: white;}
</style>
</head>
<body>
<div class="wrapper"><!-- 最外层部分 -->
<div class="banner"><!-- 轮播部分 -->
<ul class="imgList"><!-- 图片部分 -->
<li class="imgOn"><a href="#"><img src="./img/test1.jpg" width="400px" height="200px" alt="puss in boots1"></a></li>
<li><a href="#"><img src="./img/test2.jpg" width="400px" height="200px" alt="puss in boots2"></a></li>
<li><a href="#"><img src="./img/test3.jpg" width="400px" height="200px" alt="puss in boots3"></a></li>
<li><a href="#"><img src="./img/test4.jpg" width="400px" height="200px" alt="puss in boots4"></a></li>
<li><a href="#"><img src="./img/test5.jpg" width="400px" height="200px" alt="puss in boots5"></a></li>
</ul>
<div class="bg"></div> <!-- 图片底部背景层部分-->
<ul class="infoList"><!-- 图片左下角文字信息部分 -->
<li class="infoOn">puss in boots1</li>
<li>puss in boots2</li>
<li>puss in boots3</li>
<li>puss in boots4</li>
<li>puss in boots5</li>
</ul>
<ul class="indexList"><!-- 图片右下角序号部分 -->
<li class="indexOn">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</div>
<script type="text/javascript" src="./js/jquery.min.js"></script>
<script type="text/javascript">
var curIndex = 0; //当前index
// alert(imgLen);
// 定时器自动变换2.5秒每次
var autoChange = setInterval(function(){
if(curIndex < $(".imgList li").length-1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
$(".indexList").find("li").each(function(item){
$(this).hover(function(){
clearInterval(autoChange);
changeTo(item);
curIndex = item;
},function(){
autoChange = setInterval(function(){
if(curIndex < $(".imgList li").length-1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
});
});
function changeTo(num){
$(".imgList").find("li").removeClass("imgOn").hide().eq(num).fadeIn().addClass("imgOn");
$(".infoList").find("li").removeClass("infoOn").eq(num).addClass("infoOn");
$(".indexList").find("li").removeClass("indexOn").eq(num).addClass("indexOn");
}
</script>
</body>
</html>
原生JavaScript模拟实现
二、原生JavaScript实现方式
原生方式的总体思路是模拟jQuery的功能。
由于使用了大量的class操作,因此需要增加一些处理class的函数(使用id可能会更便捷)。
通过class名获取标签元素(注意:目前仅针对标签只有一个class的情况,若存在多个class可能会出错)。
//通过class获取节点
function getElementsByClassName(className){
var classArr = [];
var tags = document.getElementsByTagName('*');
for(var item in tags){
if(tags[item].nodeType == 1){
if(tags[item].getAttribute('class') == className){
classArr.push(tags[item]);
}
}
}
return classArr; //返回
}
模拟jQuery的addClass和removeClass方法。
// 判断obj是否有此class
function hasClass(obj,cls){ //class位于单词边界
return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
//给 obj添加class
function addClass(obj,cls){
if(!this.hasClass(obj,cls)){
obj.className += cls;
}
}
//移除obj对应的class
function removeClass(obj,cls){
if(hasClass(obj,cls)){
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
obj.className = obj.className.replace(reg,'');
}
}
再模拟jQuery的fadeIn和fadeOut函数。
//淡入处理函数
function fadeIn(elem){
setOpacity(elem,0); //初始全透明
for(var i = 0;i<=20;i++){ //透明度改变 20 * 5 = 100
(function(){
var level = i * 5; //透明度每次变化值
setTimeout(function(){
setOpacity(elem, level)
},i*25); //i * 25 即为每次改变透明度的时间间隔,自行设定
})(i); //每次循环变化一次
}
}
//淡出处理函数
function fadeOut(elem){
for(var i = 0;i<=20;i++){ //透明度改变 20 * 5 = 100
(function(){
var level = 100 - i * 5; //透明度每次变化值
setTimeout(function(){
setOpacity(elem, level)
},i*25); //i * 25 即为每次改变透明度的时间间隔,自行设定
})(i); //每次循环变化一次
}
}
其中设置透明度函数的处理形式如下。
//设置透明度
function setOpacity(elem,level){
if(elem.filters){
elem.style.filter = "alpha(opacity="+level+")";
}else{
elem.style.opacity = level / 100;
}
}
接下来是基本部分的用法。
首先初始化常用变量以及图片的自动切换逻辑。
var curIndex = 0, //当前index
imgArr = getElementsByClassName("imgList")[0].getElementsByTagName("li"), //获取图片组
imgLen = imgArr.length,
infoArr = getElementsByClassName("infoList")[0].getElementsByTagName("li"), //获取图片info组
indexArr = getElementsByClassName("indexList")[0].getElementsByTagName("li"); //获取控制index组
// 定时器自动变换2.5秒每次
var autoChange = setInterval(function(){
if(curIndex < imgLen -1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
//调用添加事件处理
addEvent();
其中的changeTo是处理函数,addEvent用于为右下角的那些按钮设定事件处理。
//变换处理函数
function changeTo(num){
//设置image
var curImg = getElementsByClassName("imgOn")[0];
fadeOut(curImg); //淡出当前 image
removeClass(curImg,"imgOn");
addClass(imgArr[num],"imgOn");
fadeIn(imgArr[num]); //淡入目标 image
//设置image 的 info
var curInfo = getElementsByClassName("infoOn")[0];
removeClass(curInfo,"infoOn");
addClass(infoArr[num],"infoOn");
//设置image的控制下标 index
var _curIndex = getElementsByClassName("indexOn")[0];
removeClass(_curIndex,"indexOn");
addClass(indexArr[num],"indexOn");
}
//给右下角的图片index添加事件处理
function addEvent(){
for(var i=0;i<imgLen;i++){
//闭包防止作用域内活动对象item的影响
(function(_i){
//鼠标滑过则清除定时器,并作变换处理
indexArr[_i].onmouseover = function(){
clearTimeout(autoChange);
changeTo(_i);
curIndex = _i;
};
//鼠标滑出则重置定时器处理
indexArr[_i].onmouseout = function(){
autoChange = setInterval(function(){
if(curIndex < imgLen -1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
};
})(i);
}
}
如此,原生版本的实现也完成了。
完整代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>图片轮播 js原生(淡入淡出)</title>
<style type="text/css">
body,div,ul,li,a,img{margin: 0;padding: 0;}
ul,li{list-style: none;}
a{text-decoration: none;}
.wrapper{position: relative;margin: 30px auto;width: 400px;height: 200px;}
.banner{width: 400px;height: 200px;overflow: hidden;}
.imgList{width:400px;height:200px;z-index: 10;}
.imgList li{display: none;}
.imgList .imgOn{display: inline;}
.bg{position: absolute;bottom: 0;width: 400px;height: 40px;z-index:20;opacity: 0.4;filter:alpha(opacity=40);background: black;}
.infoList{position: absolute;left: 10px;bottom: 10px;z-index: 30;}
.infoList li{display: none;}
.infoList .infoOn{display: inline;color: white;}
.indexList{position: absolute;right: 10px;bottom: 5px;z-index: 30;}
.indexList li{float: left;margin-right: 5px;padding: 2px 4px;border: 2px solid black;background: grey;cursor: pointer;}
.indexList .indexOn{background: red;font-weight: bold;color: white;}
</style>
</head>
<body>
<div class="wrapper"><!-- 最外层部分 -->
<div class="banner"><!-- 轮播部分 -->
<ul class="imgList"><!-- 图片部分 -->
<li class="imgOn"><a href="#"><img src="./img/test1.jpg" width="400px" height="200px" alt="puss in boots1"></a></li>
<li><a href="#"><img src="./img/test2.jpg" width="400px" height="200px" alt="puss in boots2"></a></li>
<li><a href="#"><img src="./img/test3.jpg" width="400px" height="200px" alt="puss in boots3"></a></li>
<li><a href="#"><img src="./img/test4.jpg" width="400px" height="200px" alt="puss in boots4"></a></li>
<li><a href="#"><img src="./img/test5.jpg" width="400px" height="200px" alt="puss in boots5"></a></li>
</ul>
<div class="bg"></div> <!-- 图片底部背景层部分-->
<ul class="infoList"><!-- 图片左下角文字信息部分 -->
<li class="infoOn">puss in boots1</li>
<li>puss in boots2</li>
<li>puss in boots3</li>
<li>puss in boots4</li>
<li>puss in boots5</li>
</ul>
<ul class="indexList"><!-- 图片右下角序号部分 -->
<li class="indexOn">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</div>
<script type="text/javascript">
var curIndex = 0, //当前index
imgArr = getElementsByClassName("imgList")[0].getElementsByTagName("li"), //获取图片组
imgLen = imgArr.length,
infoArr = getElementsByClassName("infoList")[0].getElementsByTagName("li"), //获取图片info组
indexArr = getElementsByClassName("indexList")[0].getElementsByTagName("li"); //获取控制index组
// 定时器自动变换2.5秒每次
var autoChange = setInterval(function(){
if(curIndex < imgLen -1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
//调用添加事件处理
addEvent();
//给右下角的图片index添加事件处理
function addEvent(){
for(var i=0;i<imgLen;i++){
//闭包防止作用域内活动对象item的影响
(function(_i){
//鼠标滑过则清除定时器,并作变换处理
indexArr[_i].onmouseover = function(){
clearTimeout(autoChange);
changeTo(_i);
curIndex = _i;
};
//鼠标滑出则重置定时器处理
indexArr[_i].onmouseout = function(){
autoChange = setInterval(function(){
if(curIndex < imgLen -1){
curIndex ++;
}else{
curIndex = 0;
}
//调用变换处理函数
changeTo(curIndex);
},2500);
};
})(i);
}
}
//变换处理函数
function changeTo(num){
//设置image
var curImg = getElementsByClassName("imgOn")[0];
fadeOut(curImg); //淡出当前 image
removeClass(curImg,"imgOn");
addClass(imgArr[num],"imgOn");
fadeIn(imgArr[num]); //淡入目标 image
//设置image 的 info
var curInfo = getElementsByClassName("infoOn")[0];
removeClass(curInfo,"infoOn");
addClass(infoArr[num],"infoOn");
//设置image的控制下标 index
var _curIndex = getElementsByClassName("indexOn")[0];
removeClass(_curIndex,"indexOn");
addClass(indexArr[num],"indexOn");
}
//设置透明度
function setOpacity(elem,level){
if(elem.filters){
elem.style.filter = "alpha(opacity="+level+")";
}else{
elem.style.opacity = level / 100;
}
}
//淡入处理函数
function fadeIn(elem){
setOpacity(elem,0); //初始全透明
for(var i = 0;i<=20;i++){ //透明度改变 20 * 5 = 100
(function(){
var level = i * 5; //透明度每次变化值
setTimeout(function(){
setOpacity(elem, level)
},i*25); //i * 25 即为每次改变透明度的时间间隔,自行设定
})(i); //每次循环变化一次
}
}
//淡出处理函数
function fadeOut(elem){
for(var i = 0;i<=20;i++){ //透明度改变 20 * 5 = 100
(function(){
var level = 100 - i * 5; //透明度每次变化值
setTimeout(function(){
setOpacity(elem, level)
},i*25); //i * 25 即为每次改变透明度的时间间隔,自行设定
})(i); //每次循环变化一次
}
}
//通过class获取节点
function getElementsByClassName(className){
var classArr = [];
var tags = document.getElementsByTagName('*');
for(var item in tags){
if(tags[item].nodeType == 1){
if(tags[item].getAttribute('class') == className){
classArr.push(tags[item]);
}
}
}
return classArr; //返回
}
// 判断obj是否有此class
function hasClass(obj,cls){ //class位于单词边界
return obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
//给 obj添加class
function addClass(obj,cls){
if(!this.hasClass(obj,cls)){
obj.className += cls;
}
}
//移除obj对应的class
function removeClass(obj,cls){
if(hasClass(obj,cls)){
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
obj.className = obj.className.replace(reg,'');
}
}
</script>
</body>
</html>
以上所述就是本文的全部内容了,希望大家能够喜欢。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
