原生JS实现文字在X轴方向循环移动
之前做了一个仿抖音的小项目练习,在做到视频播放页时,视频左下角有个视频信息的文字滚动效果,在网上找到了很多类似的效果,但都不太满意,所以今天就想自己来写一下实现。
主要思路
让文字像轮播图一样循环滚动,当文字内容末尾与容器末尾重合就拼接一个相同的文字内容在后面,同时当文字内容拼接过多(这里设置的大于两倍原文字内容长度时就开始删除),就删除开头的一个文字内容,保证文字内容长度合适。另外文字内容与文字内容之间的空格效果由于 innerHTML 的原因没有使用空格或者实体。因为使用空格的话html只会解析一个空格而使用实体的话innerHTML不会获取到实体解析的空格,在进行文字的拼接和删除时会造成空格太多。这里我内嵌了一个span并设置文颜色为透明来实现同样的效果。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
background: red;
width: 100px;
height: 24px;
margin-top: 500px;
margin-left: 500px;
position: relative;
overflow: hidden;
}
#box1 {
position: absolute;
font-size: 14px;
display: inline-block;
white-space: nowrap;
}
.space {
color: transparent
}
</style>
</head>
<body>
<div id="box">
<span id="box1">@只有你知道的故事<span class="space">kg</span></span>
</div>
<script>
function marquee(parent,child,time) {
let box = document.getElementById(parent);
let box1 = document.getElementById(child);
let speed = 1; //速度
let text = box1.innerHTML; //初始文字内容
let textWidth = box1.clientWidth; //单段文字内容宽度
let boxWidth = box.clientWidth; //容器宽度
let left = box1.offsetLeft; //文字相对于容器的偏移量
let difLeft = boxWidth - textWidth; //文字宽度与容器宽度的差值
//如果文字内容大于容器,文字进行滚动
if (boxWidth < textWidth) {
//定义定时器
let intervalId = setInterval(function () {
left -= speed;
box1.style.left = left + "px";
if (left == difLeft) {
//删除多余的重复text,防止内容冗杂(单单实现需求的话这个if可以不添加)
if (box1.clientWidth >= 2 * textWidth) {
box1.innerHTML = box1.innerHTML.replace(text, ""); //删除开头多余的text
left = box1.offsetLeft + textWidth; //删除后对偏移量进行重新计算
}
box1.innerHTML += text; //文字后面拼接
difLeft = boxWidth - box1.clientWidth; //重新计算文字宽度与容器宽度的差值
}
}, time)
}
}
marquee("box","box1",45);//调用函数
/*
写法二:简单粗暴
function marquee(parent,child,time) {
let box = document.getElementById(parent);
let box1 = document.getElementById(child);
let speed = 1 ; //速度
let text = box1.innerHTML; //初始文字内容
let textWidth = box1.clientWidth; //单段文字内容宽度
let boxWidth = box.clientWidth; //容器宽度
let left = box1.offsetLeft; //文字相对于容器的偏移量
let difLeft = boxWidth - textWidth; //文字宽度与容器宽度的差值
//如果文字内容大于容器,文字进行滚动
if (boxWidth < textWidth) {
//定义定时器
let intervalId = setInterval(function () {
left -= speed;
box1.style.left = left + "px";
console.log(left);
if (left == difLeft) {
//删除多余的重复text,防止内容冗杂(单单实现需求的话这个if可以不添加)
box1.innerHTML += text; //文字后面拼接
difLeft = boxWidth - box1.clientWidth; //重新计算文字宽度与容器宽度的差值
}
if (-left >= textWidth) {
left = 0; //删除后对偏移量进行重新计算
}
}, time)
}
}
*/
</script>
</body>
</html>
实现效果: