如何快速实现一个无缝轮播效果

简介: 【8月更文挑战第24天】如何快速实现一个无缝轮播效果

需求简介

轮播图是我们前端开发中的一个常见需求,在项目开发中,我们可以使用element、ant等UI库实现。某些场景,为了一个简单的功能安装一个库是没必要的,我们最好的选择就是手搓。
我们来看一个需求
image.png
上述需求核心就是实现一个无缝轮播的切换效果。以这个需求为例,我们看看最终实现效果:
240329 225619.gif

实现思路

要想实现一个无缝的轮播效果,其实非常简单,核心思想就是动态改变显示的列表而已。比如我们有这样一个数组

const list = ref([
    {
   
    name: 1, id: 1 }, 
    {
   
    name: 2, id: 2 },
    {
   
    name: 3, id: 3 }
])

如果我们想无缝切换的展示这个数据,最简单的代码就是动态的改变下面的代码的index

<template>
    <div>
       {
   
   {
   
    list[index] }}
    </div>
</template>
<script setup>
    const index = ref(0)
    const list = ref([{
   
    name: 1, id: 1 }, {
   
    name: 2, id: 2 }, {
   
    name: 2, id: 2 }])
<scriptp>

那如何实现切换的样式呢?也非常简单,我们只要给元素添加一个出现样式和离开样式即可。现在,我们来具体实现这样一个需求。

技术方案

数据的动态切换

要想实现一个数据的动态循环切换效果,是非常容易的:

<template>
 <div v-for="(build, index) in list" :key="index">
    <div v-show="index === selectIndex">
       卡片自定义内容
    </div>
 </div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
    [{
   
    name: "卡片1", id: 1 }, {
   
    name: "卡片1", id: 2 }, {
   
    name: "卡片1", id: 2 }]
)

// #计时器实例
let timer: any = null

// >计时器逻辑
const timeFuc = () => {
   
   
    timer = setInterval(() => {
   
   
      // 更改选中的index
      if (selectIndex.value >= list.value.length - 1) {
   
   
        selectIndex.value = 0
      } else {
   
   
        selectIndex.value++
      }
    }, 5000)
}

timeFuc()
<scriptp>

上述代码中,我们设置了一个定时器,定时器每5s执行一次,每次执行都会动态更改当前要显示的数据索引值,当索引值达到最大实,在将其重置。通过上述的简单代码,我们就实现了一个可以自动切换的循环渲染的卡片。

动画添加

要想实现最终效果的动态效果也非常容易,我们只需要给每个元素出现时设置一些样式,离开时设置一些样式即可。借助vue的Transition标签,我们能很容易实现这样一个效果。

如果你不了解vue的Transition组件,请去官网补充下知识:https://cn.vuejs.org/guide/built-ins/transition.html

<template>
<div class="main-content">
    <Transition v-for="(build, index) in list" :key="selectIndex">
        <div class="banner-scroll-wrap" v-show="index === selectIndex">
            卡片自定义内容
        </div>
    </Transition>
</div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
    [{
   
    name: "卡片1", id: 1 }, {
   
    name: "卡片1", id: 2 }, {
   
    name: "卡片1", id: 2 }]
)

// #计时器实例
let timer: any = null

// >计时器逻辑
const timeFuc = () => {
   
   
    timer = setInterval(() => {
   
   
      // 更改选中的index
      if (selectIndex.value >= list.value.length - 1) {
   
   
        selectIndex.value = 0
      } else {
   
   
        selectIndex.value++
      }
    }, 5000)
}

timeFuc()
<scriptp>
<style lang="less" scoped>
.main-content {
   
   
    position: relative;
    height: 100%;
    .banner-scroll-wrap {
   
   
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
    }
}

.v-enter-from {
   
   
    transform: translateX(100%);
    opacity: 0;
}

.v-enter-active,
.v-leave-active {
   
   
    transition: transform 600ms ease-in-out, opacity 600ms ease-in-out;
}

.v-enter-to {
   
   
    transform: translateX(0);
    opacity: 1;
}

.v-leave-from {
   
   
    transform: translateX(0);
    opacity: 1;
}

.v-leave-to {
   
   
    transform: translateX(-100%);
    opacity: 0;
}
<style/>

上述代码中,由于 selectIndex是动态的,元素不断地在显示与隐藏。因此,Transition标签的进入样式和离开样式会动态触发,从而形成切换效果。
v-enter是元素的进入样式,进入时,我们从最右边偏移100%的距离到正常位置,透明度从0到1,这个过程持续0.6s,实现了元素左移淡入的效果。
v-leave是元素的离开样式,离开时,我们从正常位置偏移到100%的左侧位置,透明度从1到0,这个过程持续0.6s,实现了元素左移淡出的效果。
在这些类的共同作用下,我们实现了元素的动态切换。

你可能注意到了我给元素设置了一个banner-scroll-wrap类名,并使用了position: absolute,这样设置的注意目的是保证切换离开元素的淡出效果和进入元素的淡入效果是连贯的。如果你不这样写,可能会出现样式问题。

此外,注意我给Transition设置了key="Transition",这样些会保证每次数据在切换时,transition能够重新渲染,触发元素离开和进入的样式。

至此,我们就完成了基本功能样式
240329 225619.gif

轮播的停止与恢复

很常见的一种情况就是我们需要鼠标放在卡片上时停止轮播,离开卡片的时候恢复轮播,这非常容易。

<template>
<div class="main-content"  @mouseenter="stop()" @mouseleave="start()">
    <Transition v-for="(build, index) in list" :key="selectIndex">
        <div class="banner-scroll-wrap" v-show="index === selectIndex">
            卡片自定义内容
        </div>
    </Transition>
</div>
</template>
<script setup>
const selectIndex = ref(0)
const list = ref(
    [{
   
    name: "卡片1", id: 1 }, {
   
    name: "卡片1", id: 2 }, {
   
    name: "卡片1", id: 2 }]
)

// #计时器实例
let timer: any = null

// >计时器逻辑
const timeFuc = () => {
   
   
    timer = setInterval(() => {
   
   
      // 更改选中的index
      if (selectIndex.value >= list.value.length - 1) {
   
   
        selectIndex.value = 0
      } else {
   
   
        selectIndex.value++
      }
    }, 5000)
}

  // >开启轮播
  const start = () => {
   
   
    if (timer) return
    timeFuc()
  }

  // >关闭轮播
  const stop = () => {
   
   
    clearInterval(timer)
    timer = null
  }

timeFuc()
<scriptp>
<style lang="less" scoped>
<style/>

解决重影问题

在某些情况下,我们离开这个页面很久后(浏览器切换到其他选项卡),然后在切回来的时候,可能会出现短暂的画面重影问题,这个问题也很好解决,加上下面的代码即可

<script setup>

    //...

    // 解决切屏后重影的问题
  onMounted(() => {
   
   
    document.addEventListener('visibilitychange', () => {
   
   
      // 用户息屏、或者切到后台运行 (离开页面)
      if (document.visibilityState === 'hidden') {
   
   
        stop()
      }
      // 用户打开或回到页面
      if (document.visibilityState === 'visible') {
   
   
        start()
      }
    })
  })

  onBeforeUnmount(() => stop())

<scriptp>

visibilitychange 事件:当其选项卡的内容变得可见或被隐藏时,会在 document 上触发 visibilitychange 事件。该事件不可取消。

总结

在本教程中,我们通过简单代码实现了无缝轮播效果,样式是左右切换,我们也可以通过样式控制实现上下切换的效果,比如将translateX设置为translateY即可。

 .v-enter-from {
   
   
    transform: translateY(100%);
    opacity: 0;
}

时间原因,本教程也没有对技术上做深究,也希望各位能提供自己 的思路与建议

相关文章
|
存储 缓存 前端开发
意外之惊喜!浏览器缓存优化方案,让页面加载速度飙升48.5%!
在互联网时代,页面加载速度对于用户体验至关重要。特别是在微前端架构下,更快的性能和加载速度是我们不懈追求的目标。正因如此,浏览器缓存优化方案成为了备受关注的话题。 经过对浏览器缓存优化方案的调研和实现过程,我发现了一个令人意外的发现:**页面加载速度提升了整整48.5%!** 这个令人震撼的结果在微前端架构项目中具有重要意义,同时虽然本文是针对微前端架构的,但这个浏览器缓存优化方案同样适用于其他前端项目。本文将深入探
902 0
意外之惊喜!浏览器缓存优化方案,让页面加载速度飙升48.5%!
Echarts实战案例代码(8):设置itemStyle渐变color属性实现柱图的伪3D效果的解决方案
Echarts实战案例代码(8):设置itemStyle渐变color属性实现柱图的伪3D效果的解决方案
618 0
|
7月前
|
JavaScript API C++
TypeScript 核心概念:`type` vs `interface`,如何明智选择?
TypeScript 核心概念:`type` vs `interface`,如何明智选择?
|
JavaScript 数据可视化
JS如何优雅的实现模块自动滚动展示
【8月更文挑战第22天】JS如何优雅的实现模块自动滚动展示
404 1
JS如何优雅的实现模块自动滚动展示
|
JavaScript 前端开发 搜索推荐
JS经典案例-无缝滚动轮播图(纯JS)
JS经典案例-无缝滚动轮播图(纯JS)
1267 0
|
JavaScript UED 开发者
精彩!Vue 实现消息列表向上无缝滚动!丝滑...
精彩!Vue 实现消息列表向上无缝滚动!丝滑...
|
移动开发 JavaScript HTML5
Vue3视频播放(Video)
这篇文章介绍了如何在Vue 3框架中创建一个视频播放组件(Video),支持自定义视频源、封面、自动播放等多种播放选项和样式设置。
2943 1
Vue3视频播放(Video)
|
JSON 数据格式
成功解决:Vscode中切换table页面会自动覆盖上一个问题
这篇文章分享了作者在VSCode中遇到的一个问题,即在切换Tab页面时原先的页面被自动覆盖,并通过修改设置`workbench.editor.enablePreview`解决了这个问题,使得点击文件时不再覆盖当前页面。
成功解决:Vscode中切换table页面会自动覆盖上一个问题
|
JSON JavaScript 定位技术
Echarts 绘制地图(中国、省市、区县),保姆级教程!
Echarts 绘制地图(中国、省市、区县),保姆级教程!
|
监控 数据挖掘 UED
ROI
【5月更文挑战第16天】ROI
4503 4