JS原生实现轮播图的几种方法

作者:异步漫步时间:2026-10-24 09:09:46浏览:335

本文介绍如何使用原生JavaScript和CSS3实现轮播图效果。核心思路是通过绝对定位和修改列表的left属性控制图片位置,利用overflow:hidden隐藏溢出内容。文章详细讲解了自动轮播、按钮点击切换及小圆圈导航的实现逻辑,并针对无缝滚动中首尾图片重复拼接的原理及潜在交互缺陷进行了分析。

轮播图

核心逻辑为:

大容器内包含一个宽度为容器整数倍的长列表。

通过修改列表样式的left属性实现左右滑动效果。

本文控制滑动五张图片,但HTML中实际使用七张,首尾各有一张重复图片,原因如下文所述。

轮播图

通过给容器设置overflow:hidden属性,确保仅显示视口大小的一张图片。


<body>
 <div id="container">  /*容器*/
  <div id="wrap" style="left: -400px;">  /*存放图片的列表*/
   <div class="item item5">l5</div>
   <div class="item item1">1</div>
   <div class="item item2">2</div>
   <div class="item item3">3</div>
   <div class="item item4">4</div>
   <div class="item item5">5</div>
   <div class="item item1">r1</div>
  </div>
 </div>
 <div id="key">   /*设置按钮*/   
  <div id="list">			/*点击小圆圈切换到固定图片*/
   <div class="btn1 btnNum">1</div>
   <div class="btn2 btnNum">2</div>
   <div class="btn3 btnNum">3</div>
   <div class="btn4 btnNum">4</div>
   <div class="btn5 btnNum">5</div>
  </div>
  <div id="btn">     /*向左切换和向右切换的按钮*/
   <button class="left">←</button>
   <button class="right">→</button>
  </div>
 </div>
</body>

CSS:

可为wrap列表设置flex属性,使图片单行显示,其他布局依需求调整。

注意在定义id="wrap"的节点中设置了内联样式left。因切换图片时依赖left属性,若不预先设置,DOM设置style时将无法找到该属性。


<style>
  #container {
   width: 400px;
   height: 300px;
   border: 8px rgb(8, 8, 8) solid;
   margin: 0 auto;
   margin-top: 150px;
   overflow: hidden;
   position: relative;
  }
  #wrap {
   width: 2800px;
   height: 300px;
   display: flex;
   position: relative;
  }
  .item {
   flex: 1;
   width: 400px;
   height: 300px;
  }
  .item1 {
   background-color: rosybrown;
  }
  .item2 {
   background-color: rgb(12, 226, 37);
  }
  .item3 {
   background-color: rgb(212, 221, 29);
  }
  .item4 {
   background-color: rgb(61, 27, 182);
  }
  .item5 {
   background-color: rgb(221, 23, 145);
  }
  #key {
   width: 400px;
   height: 300px;
   margin: 0 auto;
  }
  #list {
   width: 400px;
   height: 40px;
   display: flex;
   justify-content: center;
  }
  #list div {
   margin-top: 10px;
   margin-left: 10px;
   width: 20px;
   height: 20px;
   background-color: rgb(13, 162, 221);
   text-align: center;
   border-radius: 45%;
   opacity: 0.6;
  }
  #list div:hover {
   cursor: pointer;
   opacity: 1;
  }
  #btn {
   width: 400px;
   text-align: center;
  }
 </style>

完整样式如下

轮播图

每种颜色代表一张图片,并按序标注序号。起始位置为第二张图片。

首尾额外重复一张图片,是为了在滑动效果中,最后一张(倒数第二张,粉紫色)可继续向右平滑滑至第一张(实为本图第二张,浅棕色);第一张(本图第二张,浅棕色)向左滑动时可平滑滑至最后一张(实则倒数第二张)。详见下文。

1. 多种轮播方式

轮播离不开定位及修改wrap列表的left属性以实现移动。

先初始化若干数据


var wrap = document.getElementById('wrap');
var nowleft = -400;     //用于存放当前列表的left的值
var currIndex = 1;			//用于存放当前是第几个图片
//定位到几个按钮
var btnNum = document.getElementsByClassName('btnNum'); //小圆圈

var right = document.getElementsByClassName('right')[0]; //向右滑的按钮
var left = document.getElementsByClassName('left')[0];		//向左滑的按钮

1.1 定时自动轮播效果

仅讲解向左自动滑动效果

自动轮播必然需要setInterval()定时器以实现持续轮播。


function next() {
  setInterval(function() {      //设置每两秒切换一次图片
    wrap.style.transition = 'left 1s' //设定有过渡滑动的效果
		nowleft = parseInt(wrap.style.left) - 400;  //切换一次后nowleft应该减少(即向左滑)一个图片的宽度
    wrap.style.left = nowleft + 'px';   //然后将nowleft赋值给wrap的left属性
    if(parseInt(wrap.style.left) == -2400) { //判断到最后一个后,偷偷变回到最开头的位置
      setTimeout(() => {
       wrap.style.transition = 'none'  //因为是偷偷变回去,所以要取消过渡效果
       nowleft = -400;
       wrap.style.left = nowleft + 'px'
      },1200) //保证定时器的时间大于过度的时间且小于每次轮换的时间
     }
  },2000)
}

/由于wrap.style.left返回带px的字符串,故用parseInt获取前数值/

1.2 按向右滑动按钮


right.addEventListener('click',function() {
  if(nowleft >= -2000){   //判断是否到最后一个图了,没有的话就开始滑动
   nowleft -= 400;
   wrap.style.transition = 'left 1s';
   wrap.style.left = nowleft + 'px';
  }
  if(nowleft == -2400) {   //如果到最后一个图了,就偷偷换回第一张图
   setTimeout(() => {
    wrap.style.transition = 'none';
    nowleft = -400;
    wrap.style.left = nowleft + 'px';
   },1020)
  }
})

1.3 小圆圈切换图片


for(let i = 0; i < btnNum.length; i++) {
  btnNum[0].style.opacity = 1;
  btnNum[i].addEventListener('click',function() {
   wrap.style.transition = 'left 1s';
   for(let j = 0; j < btnNum.length; j++) {
    btnNum[j].style.opacity = '0.6';
   }
   btnNum[i].style.opacity = 1;
   nowleft = nowleft - (i+1 - currIndex)*400;
   currIndex = i + 1;
   wrap.style.left = nowleft + 'px';
})

本文在控制从最后一张图切换回第一张图的操作存在缺陷,因需把控序号5的图滑动到序号为r1的图需耗时1s,而wrap.style.left直接变化,不会随过渡期间位移而持续变化。故把控序号5完整滑动到r1后再偷偷切换到序号1的时间较难控制。

此外,如从序号1连续点击3下可切换至序号4;但从序号5连续点击3下则不可行,在r1切换到序号1时无法响应点击效果,因此交互差异易感别扭。

若欲改善此别扭bug,可采用防抖处理。

至此关于JS原生实现轮播图的几种方法文章介绍完毕,更多相关JS原生轮播图内容请搜索本站以前文章或继续浏览下方相关文章,希望大家以后多多支持本站!

作者最新文章