当前位置:   article > 正文

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

前端开发攻略---用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值,动画每结束一次就会抖动一次

代码:

  1. <template>
  2. <div class="aaa">
  3. <div class="box">
  4. <ul>
  5. <li v-for="item in 2">
  6. <div></div>
  7. <div></div>
  8. <div></div>
  9. <div></div>
  10. <div></div>
  11. </li>
  12. </ul>
  13. </div>
  14. </div>
  15. </template>
  16. <script setup>
  17. import { ref, reactive } from 'vue'
  18. </script>
  19. <style scoped lang="scss">
  20. .aaa{
  21. display: flex;
  22. justify-content: center;
  23. align-items: center;
  24. height: 100vh;
  25. .box {
  26. width: 1050px;
  27. height: 300px;
  28. overflow: hidden;
  29. ul {
  30. width: 200%;
  31. height: 100%;
  32. animation: scroll 2s linear infinite;
  33. & > li {
  34. width: 1050px;
  35. background-color: rgb(255, 255, 255);
  36. height: 100%;
  37. float: left;
  38. list-style: none;
  39. display: flex;
  40. & > div {
  41. width: 200px;
  42. height: 100%;
  43. margin-right: 10px;
  44. }
  45. & > div:nth-child(1) {
  46. background-color: saddlebrown;
  47. }
  48. & > div:nth-child(2) {
  49. background-color: rgb(238, 254, 0);
  50. }
  51. & > div:nth-child(3) {
  52. background-color: rgb(34, 255, 5);
  53. }
  54. & > div:nth-child(4) {
  55. background-color: rgb(10, 194, 235);
  56. }
  57. & > div:nth-child(5) {
  58. background-color: rgb(50, 9, 215);
  59. }
  60. }
  61. }
  62. ul:hover {
  63. animation-play-state: paused;
  64. }
  65. @keyframes scroll {
  66. 0% {
  67. transform: translateX(0);
  68. }
  69. 100% {
  70. transform: translateX(-780px);
  71. }
  72. }
  73. }
  74. }
  75. </style>

3、使用JS实现

优点:

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

缺点:

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

代码:

  1. <template>
  2. <div class="aaa">
  3. <div class="box">
  4. <ul ref="ulDom" @mouseenter="pause" @mouseleave="resume">
  5. <li v-for="item in 2">
  6. <div></div>
  7. <div></div>
  8. <div></div>
  9. <div></div>
  10. <div></div>
  11. </li>
  12. </ul>
  13. </div>
  14. </div>
  15. </template>
  16. <script setup>
  17. import { ref, onMounted } from 'vue'
  18. const ulDom = ref(null)
  19. let animationId = null
  20. let isPaused = false
  21. onMounted(() => {
  22. animation()
  23. })
  24. const pause = () => {
  25. cancelAnimationFrame(animationId)
  26. isPaused = true
  27. }
  28. const resume = () => {
  29. if (!isPaused) return
  30. animationId = requestAnimationFrame(animation)
  31. isPaused = false
  32. }
  33. let position = 0
  34. const animation = () => {
  35. const ulWidth = ulDom.value.offsetWidth
  36. const animate = () => {
  37. position -= 10
  38. if (position <= -(ulWidth / 2)) {
  39. position = 0
  40. }
  41. ulDom.value.style.transform = `translateX(${position}px)`
  42. animationId = requestAnimationFrame(animate)
  43. }
  44. animate()
  45. }
  46. </script>
  47. <style scoped lang="scss">
  48. .aaa{
  49. display: flex;
  50. justify-content: center;
  51. align-items: center;
  52. height: 100vh;
  53. .box {
  54. width: 1050px;
  55. height: 300px;
  56. overflow: hidden;
  57. ul {
  58. width: 200%;
  59. height: 100%;
  60. & > li {
  61. width: 1050px;
  62. background-color: rgb(255, 255, 255);
  63. height: 100%;
  64. float: left;
  65. list-style: none;
  66. display: flex;
  67. & > div {
  68. width: 200px;
  69. height: 100%;
  70. margin-right: 10px;
  71. }
  72. & > div:nth-child(1) {
  73. background-color: saddlebrown;
  74. }
  75. & > div:nth-child(2) {
  76. background-color: rgb(238, 254, 0);
  77. }
  78. & > div:nth-child(3) {
  79. background-color: rgb(34, 255, 5);
  80. }
  81. & > div:nth-child(4) {
  82. background-color: rgb(10, 194, 235);
  83. }
  84. & > div:nth-child(5) {
  85. background-color: rgb(50, 9, 215);
  86. }
  87. }
  88. }
  89. }
  90. }
  91. </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 来实现流畅的动画效果。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/616478
推荐阅读
相关标签
  

闽ICP备14008679号