/**
* 实现原理: 整体所用时间必须一致,即为最长的移动时间
* 计算最长的移动到 99%。 每百分之一 移动的长度。
* 后面所有的内容都按照此百分比进行移动。
* 最长的移动至末端。其余的短的也都移动到末端了
* 计算其余短的百分比,
* 等待最长的移动结束,移动完即可,再从头开始
*
*/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>多行不同长度文字滚动</title>
<style>
.content-scroll-box {
overflow-y: hidden;
margin: 0 20px;
}
.content-scroll-item {
font-size: 50px;
/* white-space: nowrap; */
}
</style>
</head>
<body>
<div class="a">
<div id="content-scroll-box" class="content-scroll-box">
<div id="content-scroll-item" class="content-scroll-item">多行文字、多行abcbd不同长度的文字同步滚动样式实现</div>
<div class="content-scroll-item">多行文字、多行不同长@度的文d字同步滚动样式实现</div>
<div class="content-scroll-item">多行文字、多行不d同长度的文字同12步滚动样式实现同12步!#¥%式实同12步滚动样式实</div>
<div class="content-scroll-item">多行文字、多行不@同长度E的文字同步滚g动样式实现n多行文字、多行不同长度的文字同步滚动样式实现。</div>
</div>
</div>
<script type="text/javascript">
// 获取文本框
let contentBox = document.getElementById("content-scroll-box");
contentBox.style.overflowY = 'hidden';
// 获取每行内容
let contentItems = contentBox.querySelectorAll(".content-scroll-item");
if (contentItems && contentItems.length) {
// 区分添加动太 @keyframes 名称区分 scrall-sync-[index]
let index = 1;
// 记录影藏部分的文字最大宽度 = 文字总宽度 - 一屏文字显示
let maxSubWidth = 0;
// 记录文字总宽度 : 显示的文字宽度 + 隐藏在滚动条内的宽度
let maxScrollWidth = 0;
// 文字移动的速度 【可理解为 100 px/s】
let speed = 100;
/**
* 记录显示屏幕的宽度;
* 可以利用外部容器 document.getElementById("content-scroll-box").offsetWidth 计算得出
* 本文通过 内容的宽度计算了8
*/
let width = 0;
// 第一遍 遍历内容。找到最长的单行文字。 并记录显示屏幕宽度
for (let contentItem of contentItems) {
contentItem.style.whiteSpace = 'nowrap';
// 获取显示文字宽度
let offsetWidth = contentItem.offsetWidth;
width = offsetWidth;
// 获取元素包含滚动条的宽度
let scrollWidth = contentItem.scrollWidth;
// 设置文字总宽度 含滚动条隐藏的宽度
if (maxScrollWidth < scrollWidth) {
maxScrollWidth = scrollWidth;
}
}
// 计算未显示出来内容的最大宽度 【滚动条内的宽度】
maxSubWidth = maxScrollWidth - width;
// 计算 最长滚动时间 【按照 指定 speed[最长内容 - 显示屏幕大小]需要滑动多少秒】
let maxSeconde = maxSubWidth / speed;
/**
* 实现原理: 整体所用时间必须一致,即为最长的移动时间
* 计算最长的移动到 99%。 每百分之一 移动的长度。
* 后面所有的内容都按照此百分比进行移动。
* 最长的移动至末端。其余的短的也都移动到末端了
* 计算其余短的百分比,
* 等待最长的移动结束,移动完即可,再从头开始
* 计算 滚动百分比。设置固定比例 【@keyframes 的 99% 除以 最长的未显示出来内容的最大宽度】
*/
let precentage = 99 / maxSubWidth;
// 循环添加样式
for (let contentItem of contentItems) {
// 获取当前元素在屏幕显示的宽度
let offsetWidth = contentItem.offsetWidth;
// 获取元素包含滚动条的宽度
let scrollWidth = contentItem.scrollWidth;
// 计算未显示出来的宽度内容
let subWidth = scrollWidth - offsetWidth > 0 ? scrollWidth - offsetWidth : 0;
/**
* 计算未显示出来的内容全部显示。要移动到百分比
* 计算移动到百分之多少,移动结束
* 计算公式 99 / maxSubWidth = itemPrecentage / subWidth
*/
let itemPrecentage = precentage * subWidth;
/**
* 指定百分比。将未显示的移动距离全部显示出来既可以,
* 到100%时。也为未显示距离。可控制文字滚动到最后停止不同,不显示空白
*/
const my = `@keyframes my`+ index + `{
0% {
transform: translateX(0%);
}
`+ itemPrecentage + `%{
transform: translateX(-`+ subWidth +`px);
}
100% {
transform: translateX(-`+subWidth+`px);
}
}`
const style = document.createElement('style')
style.setAttribute('type', 'text/css')
document.head.appendChild(style)
style.sheet.insertRule(my, 0)
// 添加动画。指定每行文字不同的动画。播放完成时长指定为最长的时间
contentItem.style.animation = 'my' + index + ' ' + maxSeconde +'s linear infinite';
// 移动结束后不变化
contentItem.style.animationFillMode = 'forwards';
index++;
}
}
console.log(contentBox);
</script>
</body>
</html>
方式二:
可以通过计算样式添加不同 animation-duration 实现。同事需要添加定时任务配合使用。