­

三种方式实现轮播图功能

手动实现轮播图

使用纯HTMLCSSJavaScript实现轮播图功能

position

使用position的绝对定位与相对定位实现轮播图,首先将图片全部拼接成为一行,使用overflow: hidden;将其他图片隐藏,将这一行图片加入定时任务不断进行左移,从而只显示中间的图片,对于边缘特殊处理,将第一张轮播图追加到一行图片之后,当切换到最后一张轮播图时,下一张即播放第一张图,当此图轮播完成后,将所有图片归位,提供两个DEMO,第一个是单纯的轮播不存在任何控制按钮,第二个则比较完善。

实例

<!--      简单DEMO,未实现任何控制,单纯图片轮播  -->    <!DOCTYPE html>  <html>  <head>      <title>轮播图</title>      <meta charset="utf-8">  </head>  <style type="text/css">      body{          margin: 0;          padding: 0px;      }      #carousel{          margin: auto; /* 居中 */          width: 600px; /* 设置宽度 */          position: relative; /* 相对定位 */          overflow: hidden; /* 超出隐藏 */      }      #carousel img{          width: 600px; /* 设定大小 按比例缩放 */      }      #carousel > ul {          display: flex; /* 图片处理为一行 */          position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */      }      #carousel > ul,      #carousel > ul > li{          padding: 0;          margin: 0;          list-style:none;      }  </style>  <body>      <!-- 轮播图容器 -->      <div id="carousel">          <ul> <!-- 图片容器 -->              <li>                  <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg" rel="noreferer">              </li>          </ul>      </div>  </body>      <script type="text/javascript">          var imgArr = []; // 图片数组          var curIndex = 0; // 当前显示图片          var timer = null; // 定时器            function slide(slideContainer){              var width = imgArr[curIndex].width; // 获取图片宽度,也就是每次切换图片要滑动的距离              var distanceMoved = 0; // 已经移动的距离              var step = 10; //切换的步长              var curConLeft = slideContainer.offsetLeft; // 获取ul的left              var slideInterval = setInterval(function (){ // 此定时器是为了实现切换动画                  if(Math.abs(width - distanceMoved) > step){ // 边界判定,判断已移动距离以及应移动距离的差与步长关系                      curConLeft -= step; // 大于步长则不断移动                      slideContainer.style.left = `${curConLeft}px`; // 移动                      distanceMoved += step; // 已移动距离加步长                  }else{                      clearInterval(slideInterval); // 若最后移动距离不足步长,则清除动画定时器                      slideContainer.style.left = `${curConLeft - width + distanceMoved }px`; // 直接完成此次动画                      distanceMoved = 0; // 重设移动距离为0                      if(++curIndex === imgArr.length){ // index加1,判断是否为最后一张来作边缘处理                          curIndex = 0; // 最后一张则重置index                          slideContainer.style.left = 0;  // 重置ul                      }                  }              }, 10);          }            (function start() {              var config = {                  height: "300px", // 配置高度                  interval: 5000 // 配置轮播时间间隔              }              document.getElementById("carousel").style.height = config.height; // 将轮播容器高度设定              document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 获取所有图片组成数组              var slideContainer = document.querySelector("#carousel > ul"); // 获取ul也就是一行图片的容器              var li = document.createElement("li"); // 创建<li>              var img = document.createElement("img"); // 创建新的<img>              img.src = imgArr[0].src; // 设置图片src              li.appendChild(img); // 追加<img><li>              slideContainer.appendChild(li); // 将第一张图片追加到轮播图的最后,作边缘处理              timer = setInterval(() => {slide(slideContainer)},config.interval); // 设置定时器定时切换          })();      </script>  </html>  
<!--      加入控制按钮,上一张与下一张,直接切换按钮      将第一张图片的边缘化进行处理      对浏览器页面显隐与鼠标移入移出事件的支持  -->    <!DOCTYPE html>  <html>  <head>      <title>轮播图</title>      <meta charset="utf-8">  </head>  <link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">  <style type="text/css">      body{          margin: 0;          padding: 0px;      }      #carousel{          margin: auto; /* 居中 */          width: 600px; /* 设置宽度 */          position: relative; /* 相对定位 */          overflow: hidden; /* 超出隐藏 */      }      #carousel img{          width: 600px; /* 设定大小 按比例缩放 */      }      #carousel > ul {          display: flex; /* 图片处理为一行 */          position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */      }      #carousel > ul,      #carousel > ul > li{          padding: 0;          margin: 0;          list-style:none;      }        /* 控制按钮的样式 */      #leftArrow,      #rightArrow{          position: absolute;          left: 5px;          top: 43%;          width: 25px;          height: 30px;          background-color: #eee;          display: flex;          justify-content: center;          align-items: center;          opacity: 0.7;          font-size: 20px;          cursor: pointer;      }      #rightArrow{          left: auto;          right: 5px;      }      #sliderBtn{          position: absolute;          width: 100%;          bottom: 0;          display: flex;          justify-content: flex-end;      }      .unitBtn{          width: 10px;          height: 10px;          background-color: #eee;          border-radius: 10px;          margin: 10px;          cursor: pointer;      }      .active{          background-color: #4C98F7;      }  </style>  <body>      <!-- 轮播图容器 -->      <div id="carousel">          <ul> <!-- 图片容器 -->              <li>                  <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg" rel="noreferer">              </li>          </ul>          <!-- 按钮组 -->          <div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭头切换按钮 -->          <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭头切换按钮 -->          <div id="sliderBtn"></div> <!-- 切换按钮组 -->      </div>  </body>      <script type="text/javascript">          var imgArr = []; // 图片数组          var curIndex = 0; // 当前显示图片          var timer = null; // 定时器          var clickAllow = true; // 锁,是否允许用户点击          var btnList = []; // 右下角切换按钮组            function slide(slideContainer , targetIndex = curIndex + 1){              var width = 0; // 计算切换图片要滑动的距离              if(targetIndex > curIndex){                  for(let i=curIndex;i<targetIndex;++i) width+=imgArr[i].width; // 正向切换则计算本图片到后续图片宽度              }else{                  if(targetIndex === -1) width = imgArr[imgArr.length-1].width; // 特殊处理第一张图片                  else for(let i=targetIndex;i<curIndex;++i) width+=imgArr[i].width; // 逆向切换处理宽度              }              clickAllow = false; // 不允许用户点击              var step = width/60; // 动态设置步长              step = targetIndex > curIndex ? step : -step; // 正向逆向切换              var curConLeft = slideContainer.offsetLeft; // 获取ul的left              var distanceMoved = 0; // 已经移动的距离              var slideInterval = setInterval(function (){ // 此定时器是为了实现切换动画                  if(Math.abs(width - distanceMoved) > Math.abs(step)){ // 边界判定,判断已移动距离以及应移动距离的差与步长关系                       curConLeft -= step; // 大于步长则不断移动                      slideContainer.style.left = `${curConLeft - step}px`; // 移动                      distanceMoved += Math.abs(step); // 已移动距离加步长                  }else{                      clearInterval(slideInterval); // 若最后移动距离不足步长,则清除动画定时器                      var directMove = step > 0 ? (curConLeft - width + distanceMoved) : (curConLeft + width - distanceMoved); // 正向移动与逆向移动的计算方式不同                      slideContainer.style.left = `${directMove}px`; // 直接完成此次动画                      distanceMoved = 0; // 重设移动距离为0                      curIndex = targetIndex; // 设置当前index                      if(curIndex === imgArr.length){ // index加1,判断是否为最后一张来作边缘处理                          curIndex = 0; // 最后一张则重置index                          slideContainer.style.left = `-${imgArr[0].width}px`;  // 重置ul                      }else if (curIndex === -1) {                          curIndex = imgArr.length-1; // 第一张重置index                          slideContainer.style.left = `-${slideContainer.offsetWidth - imgArr[imgArr.length-1].width - imgArr[0].width}px`;  // 重置ul                      }                      switchBtnActive(); // 右下角按钮的切换                      clickAllow = true; // 允许点击                  }              }, 10);          }            function switchBtnActive(){              btnList.forEach((v) => {                  v.className = "unitBtn"; // 设置其他按钮为灰色              })              btnList[curIndex] .className = "unitBtn active"; // 设置当前按钮为蓝色          }            function createBtnGroup(carousel,slideContainer,config){              document.getElementById("leftArrow").addEventListener('click',(e) => {                  clearInterval(timer); // 清除定时器,避免手动切换时干扰                  if(clickAllow) slide(slideContainer,curIndex-1); // 允许点击则切换上一张                  timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器              })              document.getElementById("rightArrow").addEventListener('click',(e) => {                  clearInterval(timer); // 清除定时器,避免手动切换时干扰                  if(clickAllow) slide(slideContainer,curIndex+1); // 允许点击则切换下一张                  timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器              })              var sliderBtn = document.getElementById("sliderBtn"); // 获取按钮容器的引用              imgArr.forEach((v,i) => {                  let btn = document.createElement("div"); // 制作按钮                  btn.className = i === 0 ?  "unitBtn active" : "unitBtn"; // 初设蓝色与灰色按钮样式                  btn.addEventListener('click',(e) => {                      clearInterval(timer); // 清除定时器,避免手动切换时干扰                      if(clickAllow) slide(slideContainer,i); // // 允许点击则切换                      timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器                  })                  btnList.push(btn); // 添加按钮到按钮组                  sliderBtn.appendChild(btn); // 追加按钮到按钮容器              })          }              function edgeDispose(slideContainer){              var li = document.createElement("li"); // 创建<li>              var img = document.createElement("img"); // 创建新的<img>              img.src = imgArr[0].src; // 设置图片src              li.appendChild(img); // 追加<img><li>              slideContainer.appendChild(li); // 将第一张图片追加到轮播图的最后,作边缘处理              var li2 = document.createElement("li"); // 创建<li>              var img2 = document.createElement("img"); // 创建新的<img>              img2.src = imgArr[imgArr.length-1].src; // 设置图片src              li2.appendChild(img2); // 追加<img><li>              slideContainer.insertBefore(li2,slideContainer.firstChild); // 将最后一张图片追加到轮播图的最前,作边缘处理              slideContainer.style.left = `-${imgArr[0].width}px`; // 重设ul位置          }            function eventDispose(carousel,slideContainer,config){              document.addEventListener('visibilitychange',function(){ // 浏览器切换页面会导致动画出现问题,监听页面切换                  if(document.visibilityState=='hidden') clearInterval(timer); // 页面隐藏清除定时器                  else timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器              });              carousel.addEventListener('mouseover',function(){ // 鼠标移动到容器则不切换动画,停止计时器                  clearInterval(timer); // 页面隐藏清除定时器              });              carousel.addEventListener('mouseleave',function(){ // 鼠标移出容器则开始动画                  timer = setInterval(() => {slide(slideContainer)},config.interval); // 重设定时器              });          }              (function start() {              var config = {                  height: "300px", // 配置高度                  interval: 5000 // 配置轮播时间间隔              }              var carousel = document.getElementById("carousel"); //获取容器对象的引用              carousel.style.height = config.height; // 将轮播容器高度设定              document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // 获取所有图片组成数组              var slideContainer = document.querySelector("#carousel > ul"); // 获取ul也就是一行图片的容器              edgeDispose(slideContainer); // 对边缘处理              eventDispose(carousel,slideContainer,config); // 对一些浏览器事件处理              createBtnGroup(carousel,slideContainer,config); // 按钮组的处理              timer = setInterval(() => {slide(slideContainer)},config.interval); // 设置定时器定时切换          })();      </script>  </html>  

opacity

首先通过对图片绝对定位来使图片堆叠,通过使用opacity来控制图片的显示与隐藏,即不使用Js控制轮播图的切换动画,而使用CSS动画来完成,由于是堆叠完成的,使用z-index也是可行的方案。

实例

<!DOCTYPE html>  <html>  <head>      <title>轮播图</title>      <meta charset="utf-8">  </head>  <link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">  <style type="text/css">      body{          margin: 0;          padding: 0px;      }      #carousel{          margin: auto; /* 居中 */          width: 600px; /* 设置宽度 */          position: relative; /* 相对定位 */          overflow: hidden; /* 超出隐藏 */      }      #carousel img{          position: absolute; /* 绝对定位 使图片堆叠 */          width: 600px; /* 设定大小 按比例缩放 */          transition: all .6s; /* 动画 */          opacity: 0; /* 隐藏 */      }      .imgActive{          opacity: 1 !important; /* 显示图片 最高优先级 */      }        /* 控制按钮的样式 */      #leftArrow,      #rightArrow{          position: absolute;          left: 5px;          top: 43%;          width: 25px;          height: 30px;          background-color: #eee;          display: flex;          justify-content: center;          align-items: center;          opacity: 0.7;          font-size: 20px;          cursor: pointer;          z-index: 1000;      }      #rightArrow{          left: auto;          right: 5px;      }      #sliderBtn{          position: absolute;          width: 100%;          bottom: 0;          display: flex;          justify-content: flex-end;          z-index: 1000;      }      .unitBtn{          width: 10px;          height: 10px;          background-color: #eee;          border-radius: 10px;          margin: 10px;          cursor: pointer;      }      .btnActive{          background-color: #4C98F7;      }  </style>  <body>      <!-- 轮播图容器 -->      <div id="carousel">          <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg" rel="noreferer">          <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg" rel="noreferer">          <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg" rel="noreferer">          <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg" rel="noreferer">          <!-- 按钮组 -->          <div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- 左箭头切换按钮 -->          <div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- 右箭头切换按钮 -->          <div id="sliderBtn"></div> <!-- 切换按钮组 -->      </div>  </body>      <script type="text/javascript">          var imgArr = []; // 图片数组          var curIndex = 0; // 当前显示图片          var timer = null; // 定时器          var btnList = []; // 右下角切换按钮组            function slide(targetIndex = curIndex + 1){              curIndex = targetIndex % imgArr.length; // 获取当前index              imgArr.forEach((v) => v.className = "" ); // 设置其他图片隐藏              imgArr[curIndex] .className = "imgActive"; // 设置当前index图片显示              btnList.forEach(v => v.className = "unitBtn") // 设置其他按钮为灰色              btnList[curIndex] .className = "unitBtn btnActive"; // 设置当前按钮为蓝色          }            function createBtnGroup(carousel,config){              document.getElementById("leftArrow").addEventListener('click',(e) => {                  clearInterval(timer); // 清除定时器,避免手动切换时干扰                  slide(curIndex-1); // 允许点击则切换上一张                  timer = setInterval(() => {slide()},config.interval); // 重设定时器              })              document.getElementById("rightArrow").addEventListener('click',(e) => {                  clearInterval(timer); // 清除定时器,避免手动切换时干扰                  slide(curIndex+1); // 允许点击则切换下一张                  timer = setInterval(() => {slide()},config.interval); // 重设定时器              })              var sliderBtn = document.getElementById("sliderBtn"); // 获取按钮容器的引用              imgArr.forEach((v,i) => {                  let btn = document.createElement("div"); // 制作按钮                  btn.className = i === 0 ?  "unitBtn btnActive" : "unitBtn"; // 初设蓝色与灰色按钮样式                  btn.addEventListener('click',(e) => {                      clearInterval(timer); // 清除定时器,避免手动切换时干扰                      slide(i); // // 允许点击则切换                      timer = setInterval(() => {slide()},config.interval); // 重设定时器                  })                  btnList.push(btn); // 添加按钮到按钮组                  sliderBtn.appendChild(btn); // 追加按钮到按钮容器              })          }            function eventDispose(carousel,config){              document.addEventListener('visibilitychange',function(){ // 浏览器切换页面会导致动画出现问题,监听页面切换                  if(document.visibilityState=='hidden') clearInterval(timer); // 页面隐藏清除定时器                  else timer = setInterval(() => {slide()},config.interval); // 重设定时器              });              carousel.addEventListener('mouseover',function(){ // 鼠标移动到容器则不切换动画,停止计时器                  clearInterval(timer); // 页面隐藏清除定时器              });              carousel.addEventListener('mouseleave',function(){ // 鼠标移出容器则开始动画                  timer = setInterval(() => {slide()},config.interval); // 重设定时器              });          }              (function start() {              var config = {                  height: "300px", // 配置高度                  interval: 5000 // 配置轮播时间间隔              }              var carousel = document.getElementById("carousel"); //获取容器对象的引用              carousel.style.height = config.height; // 将轮播容器高度设定              document.querySelectorAll("#carousel img").forEach((v,i) => {                  imgArr.push(v); // 获取所有图片组成数组                  v.className = i === 0 ?  "imgActive" : "";              });              eventDispose(carousel,config); // 对一些浏览器事件处理              createBtnGroup(carousel,config); // 按钮组的处理              timer = setInterval(() => {slide()},config.interval); // 设置定时器定时切换          })();      </script>  </html>  

CSS

CSS实现轮播图,完全使用CSS3动画完成轮播,主要使用animation属性与@keyframes规则,使用left控制距离,也可以使用opacity,为每个图片设置动画属性即可。

实例

<!DOCTYPE html>  <html>  <head>      <title>轮播图</title>      <meta charset="utf-8">  </head>  <link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">  <style type="text/css">      body{          margin: 0;          padding: 0px;      }      #carousel{          margin: auto; /* 居中 */          width: 600px; /* 设置宽度 */          position: relative; /* 相对定位 */          overflow: hidden; /* 超出隐藏 */          height: 300px;      }      #carousel img{          width: 600px; /* 设定大小 按比例缩放 */      }      #carousel > ul {          display: flex; /* 图片处理为一行 */          position: absolute; /* 设置绝对定位,实现相对于#carousel的绝对定位 */      }      #carousel > ul,      #carousel > ul > li{          padding: 0;          margin: 0;          list-style:none;      }        #carousel > ul{           animation: switch 10s ease 1s infinite alternate; /* 设定动画播放 */      }        #carousel > ul:hover{           animation-play-state: paused; /* 暂停动画 */      }        @keyframes switch{ /* 制定动画规则 */          0%,13%{              left: 0;          }          27%,41%{              left: -600px;          }          55%,69%{              left: -1200px;          }          83%,100% {              left: -1800px;          }      }  </style>  <body>      <!-- 轮播图容器 -->      <div id="carousel">          <ul> <!-- 图片容器 -->              <li>                  <img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg" rel="noreferer">              </li>              <li>                  <img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg" rel="noreferer">              </li>          </ul>      </div>  </body>  </html>