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

简介: 【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;
}

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

相关文章
|
7月前
|
移动开发
Uniapp 多功能富文本编辑组件 可多端使用 H5插入
Uniapp 多功能富文本编辑组件 可多端使用 H5插入
155 0
|
7月前
|
前端开发 JavaScript
uniapp移动端悬浮按钮(吸附边缘)
uniapp移动端悬浮按钮(吸附边缘)
331 0
|
SQL 移动开发 运维
5分钟自建可视化平台,在线拖拽组件也太方便了!
5分钟自建可视化平台,在线拖拽组件也太方便了!
204 0
5分钟自建可视化平台,在线拖拽组件也太方便了!
|
7月前
|
数据库
Uniapp 横向滚动抽奖页面 组件 引用即可 全端
Uniapp 横向滚动抽奖页面 组件 引用即可 全端
201 0
|
开发工具 git
vue2 实现后台管理系统左侧菜单联动实现 tab根据路由切换联动内容,并支持移动端框架
vue2 实现后台管理系统左侧菜单联动实现 tab根据路由切换联动内容,并支持移动端框架
137 0
|
前端开发 定位技术 容器
百度地图高级开发:上滑推拉菜单CSS解决方案
百度地图高级开发:上滑推拉菜单CSS解决方案
91 0
|
JavaScript 前端开发 BI
关于大屏适配我所知道的
关于大屏适配我所知道的
188 0
|
移动开发 JSON API
h5调起原生分享面板,展示更多功能方案
h5调起原生分享面板,展示更多功能方案
272 0
|
数据可视化 JavaScript 前端开发
前端可视化大屏设置全屏模式方法
前端可视化大屏设置全屏模式方法
前端可视化大屏设置全屏模式方法
|
XML Java 数据格式
HarmonyOS实战—可编辑的卡片交互
HarmonyOS实战—可编辑的卡片交互
241 0
HarmonyOS实战—可编辑的卡片交互