原生JS与jQuery实现图片淡入淡出轮播效果详解

作者:纸飞机时间:2026-10-29 08:46:21浏览:140

本文详细讲解如何使用原生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>

以上所述就是本文的全部内容了,希望大家能够喜欢。

作者最新文章