一个简易版无缝轮播图的实现思路

一个简易版无缝轮播图的实现思路

轮播图应该是每个前端的入门项目了,但是轮播图的无缝切换却难住了不少人,并且我在最近的面试中也被问到了,所以本文将介绍一个简易版的无缝轮播图的实现思路。

思路

无缝轮播图的难点无非就是第一张图和最后一张图的无缝过渡,解决好这一点,剩下的就没什么难度了。

具体实现思路:

  1. 在第一张图的的前面加一张和最后一张一样的图,同样的,在最后一张图的后面加一张和第一张一样的图。类似下图:
  2. 当划到最后一张图 copy-1 时,将过渡动画关闭,瞬间切换到 1 图
  3. 同理,当划到第一张图 copy-n 时,将过渡动画关闭,瞬间切换到 n 图

具体实现:

首先我们准备好以下元素:

html 复制代码
<div class="banner">
  <button class="left-arrow"><</button>
  <div class="banner-wrapper">
    <div class="banner-wrapper-item banner-copy3">copy-3</div>
    <div class="banner-wrapper-item banner-1">1</div>
    <div class="banner-wrapper-item banner-2">2</div>
    <div class="banner-wrapper-item banner-3">3</div>
    <div class="banner-wrapper-item banner-copy1">copy-1</div>
  </div>
  <button class="right-arrow">></button>
</div>
  • banner:轮播图的容器
  • left-arrow:左箭头
  • banner-wrapper:轮播图的内部容器,里面放置了五张图片,这里使用 div 来代替 img
  • banner-wrapper-item:轮播图的每一张图片,其中 banner-copy1 和 banner-copy3 是第一张和最后一张图片的复制品
  • right-arrow:右箭头

然后我们给它们分别添加样式:

css 复制代码
.banner {
  margin: 0 auto;
  width: 200px;
  height: 200px;
  border: 1px solid rgb(0, 0, 0);
  overflow: hidden;
  position: relative;
}

.banner-wrapper {
  display: flex;
  transition: transform 0.5s ease-in-out;
  transform: translateX(-200px); /* 初始位置 */
}

.banner-wrapper-item {
  flex-shrink: 0;
  width: 200px; /* 图片宽度 */
  height: 200px; /* 图片高度 */
}

.banner-copy3 {
  background-color: rgb(154, 170, 212);
}

.banner-1 {
  background-color: rgb(168, 230, 166);
}

.banner-2 {
  background-color: rgb(209, 174, 174);
}

.banner-3 {
  background-color: rgb(154, 170, 212);
}

.banner-copy1 {
  background-color: rgb(168, 230, 166);
}

.left-arrow {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  outline: none;
  border: none;
  cursor: pointer;
  z-index: 99;
}

.right-arrow {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  outline: none;
  border: none;
  cursor: pointer;
  z-index: 99;
}

我们给 banner 容器设置宽高为 200pxoverflowhidden,并设置 position: relative,方便后面控制 transform

banner-wrapper 设置 display: flex,让内部元素并排排布,通过控制 translateX 来实现图片的切换,并加上过渡效果。

给每个 item 设置宽度和高度为 200px,并设置背景色。

left-arrowright-arrow 设置位置和大小。

获取需要用到的元素:

javascript 复制代码
const bannerWrapper = document.querySelector('.banner-wrapper');
const leftArrow = document.querySelector('.left-arrow');
const rightArrow = document.querySelector('.right-arrow');

定义一些变量:

javascript 复制代码
const length = bannerWrapper.children.length; // 图片数量 加上前后复制的一张共五张
let cur = 1; // 当前图片索引,从 0 开始
let width = 200; // 图片宽度

重点来了,给 left-arrowright-arrow 绑定点击事件。

具体讲一下里面的逻辑,以右箭头为例:

  1. 首先判断当前所以图片是否为最后一张,如果是,则将当前图片索引设置为 1,并关闭过渡动画,瞬间切换图片 1
  2. 当切换到图片 1 后,再将当前图片索引加 1,并开启过渡动画,切换到图片 2 ,这里需要注意,这里需要用 setTimeout 函数包一下,不然两次的切换会合并到一起
  3. 如果不是最后一张,则将当前图片索引加 1,并设置 transform 值,使得图片切换到下一张。

左箭头同理,下面是具体的代码:

javascript 复制代码
// 给右箭头绑定点击事件
rightArrow.addEventListener('click', () => {
  if (cur === length - 1) {
    cur = 1;
    bannerWrapper.style.transition = 'none';
    bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
    setTimeout(() => {
      // 让上一个切换完成在执行下一个切换
      cur++;
      bannerWrapper.style.transition = 'transform 0.5s ease-in-out';
      bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
    }, 0);
    return;
  }
  cur++;
  bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
});

// 给左箭头绑定点击事件
leftArrow.addEventListener('click', () => {
  if (cur === 0) {
    cur = length - 2;
    bannerWrapper.style.transition = 'none';
    bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
    setTimeout(() => {
      // 让上一个切换完成在执行下一个切换
      cur--;
      bannerWrapper.style.transition = 'transform 0.5s ease-in-out';
      bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
    }, 0);
    return;
  }
  cur--;
  bannerWrapper.style.transform = `translateX(-${cur * width}px)`;
});

到此,一个简单的无缝切换轮播图就完成了。

当然后续还可以加上定时切换和滑动切换的功能,不过无缝轮播的思路都差不多,感兴趣的可以实现一下。

如果有更好的实现方法,欢迎交流。

相关推荐
前端snow3 小时前
ai agent --- 实现 openclaw 定时间效果
前端
码云之上4 小时前
换模型之后,Chatbot 为什么要自己做 compact?
前端·agent·前端工程化
এ慕ོ冬℘゜4 小时前
navigator 导航对象 BOM制作方法
javascript
星栈4 小时前
自定义 UI-UX-Pro-Max 的 CSV 知识库,把 AI 生成的后台拉回行业该有的样子
前端·agent·weui
研☆香4 小时前
简单的图片上传 删除 预览
前端
ITresearchGuest4 小时前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·人工智能·信息可视化
慧一居士5 小时前
Vite项目中使用Less步骤,详细使用示例
前端·css
花间相见6 小时前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
kyriewen6 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
计算机魔术师6 小时前
700吉瓦「幽灵用电」:美国AI数据中心的抢电闹剧正在失控
前端