使用JavaScript实现轮播图的任意页码切换和丝滑衔接切换效果

发布于:2025-08-01 ⋅ 阅读:(21) ⋅ 点赞:(0)

相关文章

使用JavaScript实现轮播图的自动切换和左右箭头切换效果

HTML代码

<body>
  <!-- 轮播图图片 -->
  <div class="inner">
    <ul class="innerbox">
      <li><img src="../img/tu3.jpg" alt=""></li>

      <li><img src="../img/tu1.jpg" alt=""></li>
      <li><img src="../img/tu2.jpg" alt=""></li>
      <li><img src="../img/tu3.jpg" alt=""></li>
      
      <li><img src="../img/tu1.jpg" alt=""></li>
    </ul>
    <!-- 轮播图左右箭头切换 -->
    <ul class="item">
      <li class="left" role="button"><</li>
      <li class="right" role="button">></li>
    </ul>
    <!-- 轮播图任意切换 -->
    <ul class="inner-btn">
      <li index="0" class="current"></li>
      <li index="1"></li>
      <li index="2"></li>
    </ul>
  </div>
</body>

CSS代码

*{
  margin: 0;
  padding: 0;
}
li{
  list-style-type: none;
}
/* 轮播图片 */
.inner{
  height:350px;
  width:40%;
  position: relative;
  margin: 200px auto;
  overflow: hidden;
}
.innerbox, .innerbox li, .innerbox li img{
  width: 100%;
  height: 100%;
}
.innerbox{
  width: 500%; /* 5张图片 */
  position: relative;
  left: -100%;
  display: flex;
}
.innerbox li img{
  object-fit: cover;/* 图片不变形 */
}
/* 轮播图左右箭头切换 */
.item{
  position: absolute;
  width: 85%;
  height: 50px;
  left: 40px;
  top: 150px;
}
.left, .right{
  font-size: 40px;
  font-weight: bold;
  color: #8F939F;
  width: 50px;
  height: 50px;
  text-align: center;
  line-height: 45px;
  border-radius: 25px;
  background: rgba(208, 208, 208, 0.5);
  cursor:pointer;/* 鼠标形状 */
}
.left{
  float: left;
}
.right{
  float: right;
}
/* 轮播图任意切换 */
.inner-btn{
  position: absolute;
  width: 100%;
  bottom: 20px;
  left: 45%;
  display: flex;
  cursor:pointer;/* 鼠标形状 */
}
.inner-btn li{
  margin: 5px;
  height: 16px;
  width: 16px;
  background: rgba(208, 208, 208, 0.5);
  border-radius: 50%;
}
.inner-btn li.current{
  background: rgba(0, 0, 255, 0.5);
}

JavaScript代码

实现任意页码切换

var innerbox = document.querySelector(".innerbox")
var left = document.querySelector(".left")
var right = document.querySelector(".right")
var btns = document.querySelectorAll(".item li,.inner-btn li")
var innerBtn = document.querySelectorAll(".inner-btn li")

// 获取单个轮播图的宽度
var slideWidth = document.querySelector(".innerbox li").offsetWidth
// 初始位置
innerbox.style.left = "0px"

// 核心切换方法
var change = function(num){
  // target_position目标位置
  var target_position =  parseInt(innerbox.style.left) + num
  // 图片一部到位
  // 判断边界值
  if(target_position<-slideWidth*2){
    target_position = 0
  }else if(target_position>0){
    target_position = -slideWidth*2
  }
  innerbox.style.left = target_position + "px"
}

// 小圆点样式切换核心方法
var count = 0
var light = function(num){
  count = count + num
  // 判断边界值  count值大于2,返回到0的位置;count值小于0,返回到2的位置
  if(count>2){
    count=0
  }else if(count<0){
    count=2
  }

  // 遍历  如果index值与count值相同,赋予current样式;如果不相同,去掉样式
  for(var i=0;i<innerBtn.length;i++){
    if(innerBtn[i].getAttribute("index")==count){
      innerBtn[i].className = "current"
    }else{
      innerBtn[i].className = ""
    }
  }
}

// 任意页码切换  绑定点击事件
for(var i=0;i<innerBtn.length;i++){
  innerBtn[i].onclick = function(){
    // 数据切换 小圆点与图片绑定一起
    change((count - this.getAttribute("index"))*slideWidth)
    // 样式切换
    light(this.getAttribute("index") - count)
  }
}

// 往上一张切换
left.onclick = function(){
  change(slideWidth)
  light(-1)
}
// 往下一张切换
right.onclick = function(){
  change(-slideWidth)
  light(1)
}
// 自动切换
var timer =  setInterval(right.onclick,4000)

// 通过遍历 解决手动轮播和自动轮播的冲突
for(var i=0;i<btns.length;i++){
  btns[i].onmouseenter = function(){
    clearInterval(timer)
  }
  btns[i].onmouseleave = function(){
    timer = setInterval(right.onclick, 4000)
  }
}

实现轮播丝滑衔接切换效果

修改的地方有:

  • CSS中的.innerbox宽修改为5张图片的宽
  • 初始位置修改
  • 核心切换方法修改
var innerbox = document.querySelector(".innerbox")
var left = document.querySelector(".left")
var right = document.querySelector(".right")
var btns = document.querySelectorAll(".item li,.inner-btn li")
var innerBtn = document.querySelectorAll(".inner-btn li")

// 获取单个轮播图的宽度
var slideWidth = document.querySelector(".innerbox li").offsetWidth
// 初始位置
innerbox.style.left = -slideWidth +"px"

// 核心切换方法
var flag = 0
var change = function(num){
  flag = 1
  // target_position目标位置
  var target_position =  parseInt(innerbox.style.left) + num

  // 丝滑衔接切换
  setInterval(function(){
    innerbox.style.left = (parseInt(innerbox.style.left) + num/40) + "px"
    if(parseInt(innerbox.style.left) == target_position){
      clearInterval(timer)
      if(target_position == -slideWidth * 4){
        innerbox.style.left = -slideWidth + "px"
      }else if(target_position == 0){
        innerbox.style.left = -slideWidth * 3 + "px"
      }
      flag = 0
    }
  },20)
}

// 小圆点样式切换核心方法
var count = 0
var light = function(num){
  count = count + num
  // 判断边界值  count值大于2,返回到0的位置;count值小于0,返回到2的位置
  if(count>2){
    count=0
  }else if(count<0){
    count=2
  }

  // 遍历  如果index值与count值相同,赋予current样式;如果不相同,去掉样式
  for(var i=0;i<innerBtn.length;i++){
    if(innerBtn[i].getAttribute("index")==count){
      innerBtn[i].className = "current"
    }else{
      innerBtn[i].className = ""
    }
  }
}

// 任意页码切换  绑定点击事件
for(var i=0;i<innerBtn.length;i++){
  innerBtn[i].onclick = function(){
    // 数据切换 小圆点与图片绑定一起
    change((count - this.getAttribute("index"))*slideWidth)
    // 样式切换
    light(this.getAttribute("index") - count)
  }
}

// 往上一张切换
left.onclick = function(){
  if(flag==0){
    change(slideWidth)
    light(-1)
  }
}
// 往下一张切换
right.onclick = function(){
  if(flag==0){
    change(-slideWidth)
    light(1)
  }
}
// 自动切换
var timer =  setInterval(right.onclick,4000)

// 通过遍历 解决手动轮播和自动轮播的冲突
for(var i=0;i<btns.length;i++){
  btns[i].onmouseenter = function(){
    clearInterval(timer)
  }
  btns[i].onmouseleave = function(){
    timer = setInterval(right.onclick, 4000)
  }
}

问题:修改为丝滑衔接切换代码后,会发现轮播图一直停不下来,通过打印22行的代码 console.log(parseInt(innerbox.style.left))
console.log(target_position)
发现两边的值一直不相等。
原因:宽一直是使用的百分比,换算下来会有小数点的情况,parseInt会丢弃小数部分,只取整数部分,导致与target_position计算不匹配。
解决方案:将parseInt修改为parseFloat,这样问题就解决了。

  • parseFloat:会保留小数部分,避免精度丢失
  // 丝滑衔接切换
  var timer_change = setInterval(function(){
    innerbox.style.left = (parseFloat(innerbox.style.left) + num/40) + "px"
    console.log(parseFloat(innerbox.style.left))
    console.log(target_position)

    if(parseFloat(innerbox.style.left) == target_position){
      clearInterval(timer_change)
      if(target_position == -slideWidth * 4){
        innerbox.style.left = -slideWidth + "px"
      }else if(target_position == 0){
        innerbox.style.left = -slideWidth * 3 + "px"
      }
      flag = 0
    }
  },20)

网站公告

今日签到

点亮在社区的每一天
去签到