简易实现无缝切换自动轮播

本文介绍了如何使用CSS和JavaScript实现一个简单的无缝切换自动轮播图。通过设置固定宽高的父级元素,利用CSS隐藏超出部分,并通过定时器调整图片容器的位置实现自动轮播。在轮播到最后一张图片时,通过添加额外的图片和瞬间位移,优化了过渡效果,确保了无缝衔接。同时提到了左右切换按钮的实现,但完整的代码实现将在后续更新。
摘要由CSDN通过智能技术生成

原理

  • 页面中设置一个父盒子 bannerBox,固定宽高,相当于一个窗口,超出部分隐藏
  • bannerBox 内部设置一个图片盒子 imgBox,横向(或纵向)依次排列图片
  • 添加定时器,每隔一段时间,imgBox 向左(或向上)移动一段距离
  • 为移动的过程添加 transition 过渡效果

在这里插入图片描述

  • 如上图所示,一共 4 张图,每张宽度设置为 600px,imgBox 宽度设置为 4*600 = 2400px,使得 4 张图片恰好可以在 imgBox 内横向排开。bannerBox 宽度为 600px,溢出部分隐藏,每隔 2 秒,imgBox 向左移动 600px。

初步实现

DOM 结构搭建

  • 设置 bannerBox、imgBox、img 的相关属性
<div class="bannerBox">
  <div
    class="imgBox clearfix"
    :style="{
      width: imgList.length * 600 + 'px',
    }"
  >
    <div class="sinImg" v-for="(item, index) in imgList" :key="index">
      <img :src="item" alt="" />
    </div>
  </div>
</div>
data() {
 return {
    banner1: require("@I/banner1.jpg"),
    banner2: require("@I/banner2.jpg"),
    banner3: require("@I/banner3.jpg"),
    banner4: require("@I/banner4.jpg"),
    imgList: [], // 轮播展示图片
    activeIndex: 0,
  };
},
mounted() {
  this.getImgList();
},
methods: {
  getImgList() {
    this.imgList = [ this.banner1, this.banner2, this.banner3, this.banner4 ];
  },
}
.bannerBox {
 width: 600px;
 overflow: hidden;
 border-radius: 16px;
 .imgBox {
   transform: translateX(0);
   .sinImg {
     float: left;
     img {
       width: 600px;
     }
   }
 }
}
  • imgBox 盒子范围
    在这里插入图片描述
  • 第二张图片位置
    在这里插入图片描述

添加定时器

<div class="bannerBox">
  <div
    class="imgBox clearfix"
    :style="{
      width: imgList.length * 600 + 'px',
      transform: transform,
      transition: transition,
    }"
  >
    <div class="sinImg" v-for="(item, index) in imgList" :key="index">
      <img :src="item" alt="" />
    </div>
  </div>
</div>
data() {
 return {
    banner1: require("@I/banner1.jpg"),
    banner2: require("@I/banner2.jpg"),
    banner3: require("@I/banner3.jpg"),
    banner4: require("@I/banner4.jpg"),
    imgList: [], // 轮播展示图片
    activeIndex: 0,
    timmer: null,
    transition: "transform 1s ease-in-out",
    transform: "translateX(0px)",
  };
},
mounted() {
  this.getImgList();
},
methods: {
  getImgList() {
    this.imgList = [ this.banner1, this.banner2, this.banner3, this.banner4 ];
    this.bannerFunc();
  },
}
// 自动轮播
bannerFunc() {
  this.timmer = setInterval(() => {
    // 开启轮播,自动向右
    // 标识索引加一
    this.activeIndex += 1;
    // 判断如果到了最后一张
    if (this.activeIndex > this.imgList.length - 1) {
      // 索引重置
      this.activeIndex = 0;
    }
    // 图片盒子向左移动,当前索引 * 盒子宽度
    this.transform = "translateX(" + this.activeIndex * -600 + "px)";
  }, 2000);
},
  • 上述方法在轮播图播放到最后一张 banner4 时,索引重置,会显示第一张图片 banner1,但是由于有 transition 过渡属性。视觉上的效果是,轮播图播放到 banner4 时,在 1s 的时间内,imgBox 向右移动(与轮播自动播放方向相反),快速依次略过 banner3banner2,到达 banner1

在这里插入图片描述

优化无缝衔接

  • 为了优化视觉效果,在图片数组最后添加一张 banner1,轮播图到达最后一张(banner1)时,关闭 transition 过渡属性,并且瞬间移动到数组第一张(banner1),开启新一轮的轮播
  • setInterval 定时器内部添加 setTimeout 定时器,用延时来模拟 transition 的 1s 过渡
 getImgList() {
  this.imgList = [ this.banner1, this.banner2, this.banner3, this.banner4, this.banner1 ];
  this.bannerFunc();
},
// 自动轮播
bannerFunc() {
  this.consoleTimeStr("开始调用 bannerFunc 方法", "red");
  this.timmer = setInterval(() => {
    // 开启轮播,自动向右
    this.consoleTimeStr("开始调用 toNext 方法", "blue");
    // 标识索引加一
    this.activeIndex += 1;
    // 图片盒子向左移动,当前索引 * 盒子宽度
    this.transform = "translateX(" + this.activeIndex * -600 + "px)";
    // 开启过渡效果
    this.transition = "transform 1s ease-in-out";
    // 判断如果到了最后一张(展示的是 banner1)
    if (this.activeIndex == this.imgList.length - 1) {
      // 索引重置,最后一张的 banner1 偷偷换成第一张的 banner1
      this.activeIndex = 0;
      // 在当前 interval 定时器内部,添加 timeOut 定时器
      // 关闭过渡效果,将当前图片盒子“瞬移”到初始位置
      this.consoleTimeStr("无缝衔接准备~", "yellowgreen");
      setTimeout(() => {
        this.transform = "translateX(" + this.activeIndex * -600 + "px)";
        this.transition = "none";
        this.consoleTimeStr("偷偷切换回去了!", "green");
      }, 1000);
    }
  }, 2000);
},
// 打印方法
consoleTimeStr(flag, color) {
  let time = new Date();
  let minute = time.getMinutes();
  let second = time.getSeconds();
  if (minute < 10) {
    minute = "0" + minute;
  }
  if (second < 10) {
    second = "0" + second;
  }
  let str = minute + ":" + second;
  console.log("%c" + flag + ",当前时间:" + str, "color: " + color + ";");
},

在这里插入图片描述

  • 上述打印语句可以看出,在 26:48 时,开启了 1s 的 setTimeout 定时器
  • 在这 1s 内,关闭了 transition 过渡效果,将 imgBox 位移恢复到初始位置,可以看做是瞬间位移
  • 这样做就解决了上一步骤向相反方快速移动的效果

左右切换按钮

  • 轮播可添加左右切换按钮
  • 自动切换的效果可封装为右切换效果

完整代码

<template>
  <div class="page">
    <div class="bannerBox">
      <div
        class="imgBox clearfix"
        :style="{
          width: imgList.length * 600 + 'px',
          transform: transform,
          transition: transition,
        }"
      >
        <div class="sinImg" v-for="(item, index) in imgList" :key="index">
          <img :src="item" alt="" />
        </div>
      </div>
    </div>
    <div class="dotBox clearfix">
      <div :class="{ active: activeIndex == 1 }"></div>
      <div :class="{ active: activeIndex == 2 }"></div>
      <div :class="{ active: activeIndex == 3 }"></div>
      <div :class="{ active: activeIndex == 4 }"></div>
    </div>
    <div class="btnBox">
      <div class="left" @click="toPrev('clear')">&lt;</div>
      <div class="right" @click="toNext('clear')">&gt;</div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      banner1: require("@I/banner1.jpg"),
      banner2: require("@I/banner2.jpg"),
      banner3: require("@I/banner3.jpg"),
      banner4: require("@I/banner4.jpg"),
      imgList: [], // 轮播展示图片
      activeIndex: 1,
      timmer: null,
      transition: "transform 1s ease-in-out",
      transform: "translateX(-600px)",
    };
  },
  mounted() {
    this.getImgList();
  },
  methods: {
    getImgList() {
      // 轮播数组,在第一个和最后一个补位
      this.imgList = [
        this.banner4,
        this.banner1,
        this.banner2,
        this.banner3,
        this.banner4,
        this.banner1,
      ];
      this.bannerFunc();
    },
    // 自动轮播
    bannerFunc() {
      this.consoleTimeStr("开始调用 bannerFunc 方法", "red");
      this.timmer = setInterval(() => {
        // 开启轮播,自动向右
        this.toNext();
      }, 2000);
    },
    // 切换到上一张图
    toPrev() {
      this.consoleTimeStr("开始调用 toPrev 方法", "blue");
      // 标识索引减一
      this.activeIndex -= 1;
      // 图片盒子向右移动,当前索引 * 盒子宽度
      this.transform = "translateX(" + this.activeIndex * -600 + "px)";
      // 开启过渡效果
      this.transition = "transform 1s ease-in-out";
      // 判断如果到了第一张(展示的是 banner4)
      if (this.activeIndex == 0) {
        // 索引重置,第一张的 banner4 偷偷换成倒数第二张的 banner4
        this.activeIndex = this.imgList.length - 2;
        // 在当前 interval 定时器内部,添加 timeOut 定时器
        // 关闭过渡效果,将当前图片盒子“瞬移”到初始位置
        this.consoleTimeStr("无缝衔接准备~", "yellowgreen");
        setTimeout(() => {
          this.transform = "translateX(" + this.activeIndex * -600 + "px)";
          this.transition = "none";
          this.consoleTimeStr("偷偷切换回去了!", "green");
        }, 1000);
      }
      console.log("activeIndex", this.activeIndex, "transform", this.transform);
    },
    // 切换到下一张图
    toNext() {
      this.consoleTimeStr("开始调用 toNext 方法", "blue");
      // 标识索引加一
      this.activeIndex += 1;
      // 图片盒子向左移动,当前索引 * 盒子宽度
      this.transform = "translateX(" + this.activeIndex * -600 + "px)";
      // 开启过渡效果
      this.transition = "transform 1s ease-in-out";
      // 判断如果到了最后一张(展示的是 banner1)
      if (this.activeIndex == this.imgList.length - 1) {
        // 索引重置,最后一张的 banner1 偷偷换成第二张的 banner1
        this.activeIndex = 1;
        // 在当前 interval 定时器内部,添加 timeOut 定时器
        // 关闭过渡效果,将当前图片盒子“瞬移”到初始位置
        this.consoleTimeStr("无缝衔接准备~", "yellowgreen");
        setTimeout(() => {
          this.transform = "translateX(" + this.activeIndex * -600 + "px)";
          this.transition = "none";
          this.consoleTimeStr("偷偷切换回去了!", "green");
        }, 1000);
      }
      console.log("activeIndex", this.activeIndex, "transform", this.transform);
    },
    // 打印方法
    consoleTimeStr(flag, color) {
      let time = new Date();
      let minute = time.getMinutes();
      let second = time.getSeconds();
      if (minute < 10) {
        minute = "0" + minute;
      }
      if (second < 10) {
        second = "0" + second;
      }
      let str = minute + ":" + second;
      console.log("%c" + flag + ",当前时间:" + str, "color: " + color + ";");
    },
  },
};
</script>
<style lang="scss" scoped>
.page {
  width: 600px;
  position: relative;
  margin: 20px auto;
  .bannerBox {
    width: 600px;
    overflow: hidden;
    border-radius: 16px;
    .imgBox {
      .sinImg {
        float: left;
        img {
          width: 600px;
        }
      }
    }
  }
  .dotBox {
    width: 70px;
    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    div {
      float: left;
      width: 10px;
      height: 10px;
      border-radius: 50%;
      margin-right: 10px;
      cursor: pointer;
      background: rgba(255, 255, 255, 0.2);
      &:last-child {
        margin-right: 0;
      }
      &.active {
        background: rgba(255, 255, 255, 0.9);
      }
    }
  }
  .btnBox {
    width: 100%;
    height: 80px;
    line-height: 80px;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    div {
      position: absolute;
      cursor: pointer;
      font-size: 36px;
      color: #fff;
      font-weight: bold;
      font-family: cursive;
    }
    .left {
      left: 10px;
    }
    .right {
      right: 10px;
    }
  }
}
.clearfix:after {
  content: "";
  display: block;
  clear: both;
  visibility: hidden;
}
</style>

未完待续

  • 上述效果暂时未考虑点击左右切换按钮时,停止定时器的效果,后续有时间再补充
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现轮播自动轮播的关键是定时器和 JavaScript 代码。 在 HTML 中,轮播图通常是用图片和按钮组成的,所以你需要使用 HTML 和 CSS 来创建轮播图的基本结构和样式。具体来说,你需要创建一个包含图片和按钮的父容器,并用 CSS 设置其宽度和高度等样式属性。 接下来,你需要编写 JavaScript 代码来实现自动轮播。首先,你需要使用 setInterval 函数创建一个定时器,以便定时切换轮播图。在定时器的回调函数中,你需要获取当前轮播图的索引,然后将其与下一张轮播图的索引进行比较,以决定是否需要切换轮播图。如果需要切换,则将当前轮播图的显示状态设置为隐藏,将下一张轮播图的显示状态设置为显示,并将当前轮播图的索引更新为下一张轮播图的索引。 最后,你需要为轮播图上的按钮添加事件监听函数,以便用户可以手动切换轮播图。在事件监听函数中,你需要实现与定时器回调函数类似的逻辑,但是需要手动更新当前轮播图的索引。 下面是一个简单的示例代码,可以帮助你更好地理解如何实现轮播图的自动轮播: ```html <div class="slider"> <img src="img1.jpg" class="slide active"> <img src="img2.jpg" class="slide"> <img src="img3.jpg" class="slide"> <div class="controls"> <button class="prev">Prev</button> <button class="next">Next</button> </div> </div> ``` ```css .slider { width: 600px; height: 400px; position: relative; } .slider img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: none; } .slider img.active { display: block; } .slider .controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); } .slider .controls button { font-size: 16px; padding: 8px 20px; margin: 0 10px; } ``` ```js const slides = document.querySelectorAll('.slider .slide'); const prevButton = document.querySelector('.slider .prev'); const nextButton = document.querySelector('.slider .next'); let currentSlide = 0; // 切换轮播图 function changeSlide(index) { slides[currentSlide].classList.remove('active'); slides[index].classList.add('active'); currentSlide = index; } // 自动轮播 setInterval(() => { let nextSlide = currentSlide + 1; if (nextSlide >= slides.length) { nextSlide = 0; } changeSlide(nextSlide); }, 3000); // 手动切换轮播图 prevButton.addEventListener('click', () => { let prevSlide = currentSlide - 1; if (prevSlide < 0) { prevSlide = slides.length - 1; } changeSlide(prevSlide); }); nextButton.addEventListener('click', () => { let nextSlide = currentSlide + 1; if (nextSlide >= slides.length) { nextSlide = 0; } changeSlide(nextSlide); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值