Vue跑马灯marquee组件(双端通用)
目录一、实现效果二、实现过程三、js版本源码四、Vue组件源码一、实现效果二、实现过程前言:最开始用间隔器方案制作了一个跑马灯,但是放在移动端中会出现严重的掉帧卡顿现象,于是整理思路后采用transition方案制作一个从右到左的动画处理问题思路整理:1.过渡是需要设定时间的,但是跑马灯中的文本可能是长短不一的解决方案:根据文本的总宽度(即文本总长)设定过渡时间,假设文本宽度500px,我们将其除
目录
一、实现效果
二、实现过程
前言:最开始用间隔器方案制作了一个跑马灯,但是放在移动端中会出现严重的掉帧卡顿现象,于是整理思路后采用transition方案制作一个从右到左的动画处理问题
思路整理:
1.过渡是需要设定时间的,但是跑马灯中的文本可能是长短不一的
解决方案:根据文本的总宽度(即文本总长)设定过渡时间,假设文本宽度500px,我们将其除以50,即过渡时间为10s
原生js表示如下:
const text = document.getElementsByClassName("text")[0] // 文本
const textWidth = text.clientWidth // 文本的总宽度
const tranTime = textWidth / 50 // 根据文本宽度设置过渡时间
text.style.transition = "left " + tranTime + "s linear" // 滚动前绑定过渡属性
2.要想持续滚动需要重复触发滚动的事件
解决方案:通过上文的过渡时间设定一个重复时间
原生js表示如下:
const againTime = tranTime * 1000 + 1000 // 重新开始滚动时间计算(动态)
// 开始滚动
function textRoll() {
// 滚动操作
// ``````
setTimeout(() => {
textRoll()
}, againTime);
}
3.接下来实现文本滚动效果
1) 先将文本设定在容器最右侧
2) 为文本绑定设定好的过渡属性,例:transition: left 10s linear
3) 因为有过渡属性,此时再将文本设定到容器最左侧,就会产生一个从右向左的移动的
过渡
原生js表示如下:
function textRoll() {
text.style.transition = "left " + tranTime + "s linear" // 滚动前绑定过渡属性
text.style.left = -textWidth + "px" // 向容器最左移动
setTimeout(() => {
setTimeout(() => {
textRoll()
}, 0);
}, againTime);
}
4.到目前就能有一次完整的滚动了,接下来是定义重新滚动
让文本回到容器最右侧,但是目前文本已经有过渡属性了,如果改变其left会导致他从左向右滚动,所以要先清除过渡属性,再改变其left到容器最右侧,然后用一开始设定的再次滚动时间绑定定时器
function textRoll() {
text.style.transition = "left " + tranTime + "s linear" // 滚动前绑定过渡属性
text.style.left = -textWidth + "px" // 向容器最左移动
setTimeout(() => {
// 还原文本位置
text.style.transition = "" // 还原前需清除过渡
text.style.left = wrapperWidth + "px"
setTimeout(() => {
textRoll()
}, 0);
}, againTime);
}
三、js版本源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跑马灯</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper {
width: 60%;
height: 30px;
background-color: #000;
overflow: hidden;
position: relative;
}
.text {
color: #fff;
white-space: nowrap;
line-height: 30px;
position: absolute;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="text">如何四纪为天子,不及卢家有莫愁。</div>
</div>
<script>
const wrapper = document.getElementsByClassName("wrapper")[0] // 容器
const text = document.getElementsByClassName("text")[0] // 文本
const wrapperWidth = wrapper.clientWidth // 容器的总宽度
const textWidth = text.clientWidth // 文本的总宽度
text.style.left = wrapperWidth + "px" // 开始滚动前设定文本在容器最右侧以外
const tranTime = textWidth / 50 // 根据文本宽度设置过渡时间
const againTime = tranTime * 1000 + 1000 // 重新开始滚动时间计算(动态)
setTimeout(() => {
textRoll()
}, 0);
// 开始滚动
function textRoll() {
text.style.transition = "left " + tranTime + "s linear" // 滚动前绑定过渡属性
text.style.left = -textWidth + "px" // 向容器最左移动
setTimeout(() => {
// 还原文本位置
text.style.transition = "" // 还原前需清除过渡
text.style.left = wrapperWidth + "px"
setTimeout(() => {
textRoll()
}, 0);
}, againTime);
}
</script>
</body>
</html>
四、Vue组件源码
<template>
<div class="mobile-marquee">
<img src="~assets/img/home/notice/notice.png" alt="" />
<div class="mobile-marquee-wrapper" ref="wrapper">
<div
class="mobile-marquee-text"
ref="text"
:style="{ 'left': textLeft, 'transition': textTransition }"
>
{{ text }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
text:
"海外徒闻更九州,他生未卜此生休。 空闻虎旅传宵柝,无复鸡人报晓筹。 此日六军同驻马,当时七夕笑牵牛。 如何四纪为天子,不及卢家有莫愁。",
url: "",
textLeft: "",
textTransition: ""
};
},
methods: {
// 跑马灯运作
marquee() {
const _this = this
const wrapperWidth = this.$refs.wrapper.clientWidth; // 容器的总宽度
const textWidth = this.$refs.text.clientWidth; // 文本的总宽度
const transTime = textWidth / 50; // 根据文本宽度设置过渡时间
const againTime = transTime * 1000 + 1000; // 重新开始滚动时间计算(动态)
this.textLeft = wrapperWidth + "px"; // 开始滚动前设定文本在容器最右侧以外
setTimeout(() => {
textRoll()
}, 0);
function textRoll() {
_this.textTransition = "left " + transTime + "s linear"; // 滚动前绑定过渡属性
_this.textLeft = -textWidth + "px"; // 向容器最左移动
setTimeout(() => {
// 还原文本位置
_this.textTransition = "none"; // 还原前需清除过渡
_this.textLeft = wrapperWidth + "px";
setTimeout(() => {
textRoll();
}, 0);
}, againTime);
}
},
},
mounted() {
this.marquee();
}
};
</script>
<style>
.mobile-marquee {
display: flex;
align-items: center;
height: 40px;
margin: 0 16px;
}
.mobile-marquee-wrapper {
flex: 1;
height: 40px;
overflow: hidden;
position: relative;
}
.mobile-marquee img {
width: 14px;
height: 12px;
margin-right: 7px;
}
.mobile-marquee-text {
color: #333;
white-space: nowrap;
line-height: 40px;
position: absolute;
}
</style>
更多推荐
所有评论(0)