前端开发攻略---用Vue实现无限滚动的几种方法

目录

1、原理

2、使用CSS动画

代码:

3、使用JS实现

代码:


1、原理

  1. 复制内容:将需要滚动的内容复制一次,并将这些副本放置在原始内容的后面。这样,当用户滚动到内容的末尾时,就会无缝地切换回到内容的起始位置。

  2. 动画滚动 :使用 CSS 或 JavaScript 动画来滚动内容。通常,通过改变元素的位置(例如使用 transform 属性的 translate 函数)来实现滚动效果。

  3. 无限循环:当滚动到最后一个复制的内容时,将滚动位置重新设置为内容的起始位置,以创建无限循环的效果。这通常需要检测滚动位置,并在必要时进行调整。

  4. 控制滚动:根据用户的交互(例如鼠标移入/移出、滚动等),控制滚动的开始和暂停。这通常涉及使用事件处理程序来监听用户的交互,并相应地调整滚动的状态。

2、使用CSS动画

优点:

  1. 性能优化: CSS 动画通常会通过浏览器的硬件加速来执行,因此在性能方面可能更有效率。
  2. 简单易用: 使用 CSS 实现无限滚动通常比使用 JavaScript 更简单,并且可以通过几行 CSS 代码就能实现基本的效果。
  3. 响应式设计: CSS 可以轻松实现响应式设计,使得滚动效果在不同设备上具有一致的表现。
  4. 动画流畅性: 使用 CSS 实现的动画通常更加平滑,因为浏览器会根据自身的渲染节奏来处理动画效果。

缺点:

  1. 功能受限: 使用 CSS 实现的滚动效果通常比较基础,功能上受到一定的限制,例如无法实现复杂的动态交互或逻辑控制。
  2. 浏览器兼容性: 某些高级的 CSS 特性可能不被一些旧版本的浏览器所支持,这可能会导致在一些浏览器上无法正常显示滚动效果。
  3. 难以调试: 对于复杂的 CSS 动画效果,调试起来可能相对困难,特别是涉及到交互逻辑时。
  4. 性能消耗: 虽然 CSS 动画通常有较好的性能,但对于复杂的动画效果,可能会引起页面的重绘和重排,导致性能下降。

难受的点:当滚动容器内的元素使用了margin值,动画每结束一次就会抖动一次

代码:

html 复制代码
<template>
  <div class="aaa">
    <div class="box">
      <ul>
        <li v-for="item in 2">
          <div></div>
          <div></div>
          <div></div>
          <div></div>
          <div></div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

</script>

<style scoped lang="scss">
.aaa{
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  .box {
    width: 1050px;
    height: 300px;
    overflow: hidden;
    ul {
      width: 200%;
      height: 100%;
      animation: scroll 2s linear infinite;

      & > li {
        width: 1050px;
        background-color: rgb(255, 255, 255);
        height: 100%;
        float: left;
        list-style: none;
        display: flex;
        & > div {
          width: 200px;
          height: 100%;
          margin-right: 10px;
        }
        & > div:nth-child(1) {
          background-color: saddlebrown;
        }
        & > div:nth-child(2) {
          background-color: rgb(238, 254, 0);
        }
        & > div:nth-child(3) {
          background-color: rgb(34, 255, 5);
        }
        & > div:nth-child(4) {
          background-color: rgb(10, 194, 235);
        }
        & > div:nth-child(5) {
          background-color: rgb(50, 9, 215);
        }
      }
    }
    ul:hover {
      animation-play-state: paused;
    }
    @keyframes scroll {
      0% {
        transform: translateX(0);
      }
      100% {
        transform: translateX(-780px);
      }
    }
  }
}
</style>

3、使用JS实现

优点:

  1. 灵活性: 使用 JavaScript 实现无限滚动效果可以更灵活地控制动画的行为,包括速度、加速度、缓动效果等,以及根据用户交互进行动态调整。
  2. 功能丰富: JavaScript 提供了丰富的 API 和库,可以实现复杂的交互效果和逻辑控制,使得滚动效果更具创意和个性化。
  3. 兼容性: JavaScript 可以在几乎所有现代浏览器中运行,因此更具有跨浏览器兼容性。
  4. 调试方便: 使用 JavaScript 编写的动画代码通常更易于调试,因为可以通过控制台输出、断点调试等方式进行调试。

缺点:

  1. 性能消耗: JavaScript 动画可能会消耗更多的 CPU 和内存资源,尤其是对于复杂的动画效果或需要频繁计算的情况。
  2. 编码复杂度: 相对于使用 CSS 实现,使用 JavaScript 实现动画通常需要更多的编码工作,因为需要处理更多的逻辑和交互细节。
  3. 性能不稳定: 由于 JavaScript 是单线程执行的,当 JavaScript 代码执行时间过长或执行过程中阻塞了主线程,可能会导致页面卡顿或动画不流畅的问题。
  4. 兼容性问题: 某些低版本或旧版浏览器可能不支持或支持不完整某些 JavaScript 特性,导致在这些浏览器上无法正常运行动画效果。

代码:

html 复制代码
<template>
  <div class="aaa">
    <div class="box">
      <ul ref="ulDom" @mouseenter="pause" @mouseleave="resume">
        <li v-for="item in 2">
          <div></div>
          <div></div>
          <div></div>
          <div></div>
          <div></div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
const ulDom = ref(null)
let animationId = null
let isPaused = false

onMounted(() => {
  animation()
})
const pause = () => {
  cancelAnimationFrame(animationId)
  isPaused = true
}

const resume = () => {
  if (!isPaused) return
  animationId = requestAnimationFrame(animation)
  isPaused = false
}
let position = 0
const animation = () => {
  const ulWidth = ulDom.value.offsetWidth
  const animate = () => {
    position -= 10
    if (position <= -(ulWidth / 2)) {
      position = 0
    }
    ulDom.value.style.transform = `translateX(${position}px)`
    animationId = requestAnimationFrame(animate)
  }
  animate()
}
</script>

<style scoped lang="scss">
.aaa{
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  .box {
    width: 1050px;
    height: 300px;
    overflow: hidden;
    ul {
      width: 200%;
      height: 100%;
      & > li {
        width: 1050px;
        background-color: rgb(255, 255, 255);
        height: 100%;
        float: left;
        list-style: none;
        display: flex;
        & > div {
          width: 200px;
          height: 100%;
          margin-right: 10px;
        }
        & > div:nth-child(1) {
          background-color: saddlebrown;
        }
        & > div:nth-child(2) {
          background-color: rgb(238, 254, 0);
        }
        & > div:nth-child(3) {
          background-color: rgb(34, 255, 5);
        }
        & > div:nth-child(4) {
          background-color: rgb(10, 194, 235);
        }
        & > div:nth-child(5) {
          background-color: rgb(50, 9, 215);
        }
      }
    }
  }
}
</style>

代码解释:

  1. 引入依赖

    • 使用了 Vue 3 的 refonMounted 函数来创建响应式数据和在组件挂载后执行动画。
  2. 初始化变量

    • ulDom:通过 ref 创建的引用,指向 <ul> 元素,用于获取其宽度以及控制动画。
    • animationId:用于存储动画帧的 ID,方便后续取消动画。
    • isPaused:用于记录动画是否处于暂停状态。
  3. 初始化动画 (onMounted 钩子):

    • 调用 animation 函数启动动画。
  4. 暂停和继续动画

    • pause 方法:取消当前动画帧的执行,并将 isPaused 标志设置为 true,表示动画暂停。
    • resume 方法:如果动画没有处于暂停状态,则重新启动动画。
  5. 动画逻辑 (animation 函数):

    • 获取 <ul> 元素的宽度,以便在动画中使用。
    • 定义 animate 函数,该函数负责实际的动画逻辑。
    • animate 函数中,每帧向左移动 10px,直到移动到一半宽度的位置时,将位置重置为 0,从而实现无限滚动的效果。
    • 使用 requestAnimationFrame 来实现流畅的动画效果。
相关推荐
I_Am_Me_11 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
℘团子এ22 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z27 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
星星会笑滴31 分钟前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
前端百草阁1 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
zwjapple1 小时前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
临枫5411 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript