目录
1、原理
复制内容:将需要滚动的内容复制一次,并将这些副本放置在原始内容的后面。这样,当用户滚动到内容的末尾时,就会无缝地切换回到内容的起始位置。
动画滚动 :使用 CSS 或 JavaScript 动画来滚动内容。通常,通过改变元素的位置(例如使用
transform
属性的translate
函数)来实现滚动效果。无限循环:当滚动到最后一个复制的内容时,将滚动位置重新设置为内容的起始位置,以创建无限循环的效果。这通常需要检测滚动位置,并在必要时进行调整。
控制滚动:根据用户的交互(例如鼠标移入/移出、滚动等),控制滚动的开始和暂停。这通常涉及使用事件处理程序来监听用户的交互,并相应地调整滚动的状态。
2、使用CSS动画
优点:
- 性能优化: CSS 动画通常会通过浏览器的硬件加速来执行,因此在性能方面可能更有效率。
- 简单易用: 使用 CSS 实现无限滚动通常比使用 JavaScript 更简单,并且可以通过几行 CSS 代码就能实现基本的效果。
- 响应式设计: CSS 可以轻松实现响应式设计,使得滚动效果在不同设备上具有一致的表现。
- 动画流畅性: 使用 CSS 实现的动画通常更加平滑,因为浏览器会根据自身的渲染节奏来处理动画效果。
缺点:
- 功能受限: 使用 CSS 实现的滚动效果通常比较基础,功能上受到一定的限制,例如无法实现复杂的动态交互或逻辑控制。
- 浏览器兼容性: 某些高级的 CSS 特性可能不被一些旧版本的浏览器所支持,这可能会导致在一些浏览器上无法正常显示滚动效果。
- 难以调试: 对于复杂的 CSS 动画效果,调试起来可能相对困难,特别是涉及到交互逻辑时。
- 性能消耗: 虽然 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实现
优点:
- 灵活性: 使用 JavaScript 实现无限滚动效果可以更灵活地控制动画的行为,包括速度、加速度、缓动效果等,以及根据用户交互进行动态调整。
- 功能丰富: JavaScript 提供了丰富的 API 和库,可以实现复杂的交互效果和逻辑控制,使得滚动效果更具创意和个性化。
- 兼容性: JavaScript 可以在几乎所有现代浏览器中运行,因此更具有跨浏览器兼容性。
- 调试方便: 使用 JavaScript 编写的动画代码通常更易于调试,因为可以通过控制台输出、断点调试等方式进行调试。
缺点:
- 性能消耗: JavaScript 动画可能会消耗更多的 CPU 和内存资源,尤其是对于复杂的动画效果或需要频繁计算的情况。
- 编码复杂度: 相对于使用 CSS 实现,使用 JavaScript 实现动画通常需要更多的编码工作,因为需要处理更多的逻辑和交互细节。
- 性能不稳定: 由于 JavaScript 是单线程执行的,当 JavaScript 代码执行时间过长或执行过程中阻塞了主线程,可能会导致页面卡顿或动画不流畅的问题。
- 兼容性问题: 某些低版本或旧版浏览器可能不支持或支持不完整某些 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>
代码解释:
引入依赖:
- 使用了 Vue 3 的
ref
和onMounted
函数来创建响应式数据和在组件挂载后执行动画。初始化变量:
ulDom
:通过ref
创建的引用,指向<ul>
元素,用于获取其宽度以及控制动画。animationId
:用于存储动画帧的 ID,方便后续取消动画。isPaused
:用于记录动画是否处于暂停状态。初始化动画 (
onMounted
钩子):
- 调用
animation
函数启动动画。暂停和继续动画:
pause
方法:取消当前动画帧的执行,并将isPaused
标志设置为true
,表示动画暂停。resume
方法:如果动画没有处于暂停状态,则重新启动动画。动画逻辑 (
animation
函数):
- 获取
<ul>
元素的宽度,以便在动画中使用。- 定义
animate
函数,该函数负责实际的动画逻辑。- 在
animate
函数中,每帧向左移动 10px,直到移动到一半宽度的位置时,将位置重置为 0,从而实现无限滚动的效果。- 使用
requestAnimationFrame
来实现流畅的动画效果。