一. 背景
在前端开发中,不少网站和应用都会运用到动态效果来吸引用户的注意,并提升用户体验。文字跑马灯是一种常见的动态效果,通过文字不断滚动来展示内容,吸引用户的注意力。
最近的一个项目就需要实现文字跑马灯效果,来向用户展示一些公告信息。具体需求是:当文本超出页面宽度时,需要文字滚动,否则不进行滚动。
其实,在 HTML 元素中,<marquee>
元素是原生的文字滚动组件,遗憾的是不支持自动判断文字宽度是否超出页面,而且该元素已弃用,官方已不再建议使用了。
因此,本篇文章通过简单的思路及原理分析,来实现文字跑马灯效果,轻松实现文字的自动按需滚动。
二. Marquee 元素
在进行自己实现文字跑马灯效果之前,我们先来看一下 HTML 元素中的<marquee>
元素。
HTML marquee 元素(<marquee>
)用来插入一段滚动的文字,可以使用它的属性控制当文本超出容器时实现文字滚动效果。
注意:
<marquee>
元素已经过时,官方建议不要再使用。可能一些浏览器仍然支持它,或许不久从相关的 web 标准中移除,请尽量不要使用该特性,因为可能该特性随时可能无法正常工作
虽然已经移除,我们可以学习一下<marquee>
的滚动 API,借鉴一下来拓展一下思路:
简单说几个重点的 API:
-
behavior:文本在 marquee 元素内如何滚动。 scroll,slide 和 alternate。默认值为 scroll。
-
bgcolor:颜色名称或十六进制值设置背景颜色。
-
scrollamount:每次滚动时移动的长度,单位:像素。默认值为 6。
-
direction:文本滚动的方向。可选值有 left, right, up and down。默认值为 left。
-
loop:文本滚动的次数。如果未指定值,默认值为 −1,表示 marquee 将连续滚动。
-
width:宽度,单位:像素或百分比值。
-
height:高度,单位同上。
遗憾的是,我查看了它的所有 API,发现它并不支持自动判断文字宽度的操作。下面我以一个简单的例子使用 marquee
实现滚动效果:
<marquee loop="-1" behavior="scroll" direction="left" width="200" bgcolor="red">This text will scroll from right to left
</marquee>
通过以上简单的代码,marquee
版的文字滚动就实现了,如下所示:
由于<marquee>
元素已被官方弃用,同时也不支持配置动态滚动,更多详细内容文档参考:marquee MDN 文档
因此,接下来我们自己实现一个文字跑马灯效果。
三. 如何实现文字滚动的分析
需求分析:实现一款文字跑马灯效果,同时需要自动判断文本内容的宽度,如果超出容器宽度,则进行文本滚动显示;否则文本不进行滚动。
思路分析:
-
判断容器的宽度和文字内容的宽度,当文字宽度大于容器宽度时,文字滚动;当文字宽度小于容器宽度时,文字不滚动。
-
实现滚动动画,当文字超出容器时,文字由左向右的进行循环滚动。
因此实现这个组件的的重点就是以上思路分析中的要点,接下来我们看一下如何实现?
1. 第一步:判断文字是否超出容器
判断文字是否超出容器,具体操作为,判断文字的内容宽度 > 容器的宽度?而获取这两个元素的宽度可以通过以下这两个 API 来获取:
-
获取文字的宽度:
el.getBoundingClientRect().width
。 -
获取容器的宽度:
el.clientWidth
。 -
当
el.getBoundingClientRect().width > el.clientWidth
,则需要滚动。
说明:el.getBoundingClientRect().width
和 el.clientWidth
是用来获取元素宽度的两种属性,它们之间有一些区别,理解好这两个区别就成功了一半。
① el.getBoundingClientRect().width
el.getBoundingClientRect()
获取的是 DOM 元素相对于窗口的坐标集合,集合中有多个属性,其中的 width
属性就是相对于视口的元素的宽度。
-
通过调用元素的
getBoundingClientRect()
方法来获取元素相对于视口的位置信息,并返回一个包含元素位置、尺寸等属性的 DOMRect 对象。 -
width
属性表示元素的宽度,包括元素的内容、内边距和边框,但不包括外边距。它会计算元素的实际宽度,包括可能存在的滚动条。 -
因为
width
属性是相对于视口的,所以当页面发生滚动时,元素的位置和尺寸可能会发生改变。
② el.clientWidth
获取元素可视部分的宽度通过 el.clientWidth
这个 API
来获取,如下图所示浏览器常用高度的示意图,从图中,很清晰的可以看到clientWidth
指示。
-
通过调用元素的
clientWidth
方法用来获取元素的内容宽度,包括内边距,但是不包括边框和外边距。 -
clientWidth
通常用来获取元素可视部分的宽度,即不包括滚动条和隐藏部分的宽度。 -
clientWidth
不会受到页面滚动的影响,它表示的是元素在不考虑滚动的情况下的宽度。
综上所述,el.getBoundingClientRect().width
返回的是元素相对于视口的位置和尺寸信息中的宽度,包含了内边距和边框,并可能受到滚动的影响;而 el.clientWidth
获取的是元素内容部分的宽度,不包括内边距和边框,也不受滚动的影响。
因此根据具体的需求,获取文字的宽度使用的是el.getBoundingClientRect().width
,而获取容器的宽度使用的是el.clientWidth
。
<div class="marquee-container"><div class="marquee-text">这是一段需要滚动显示的文本内容~</div>
</div>
2. 第二步:滚动的动画实现
要实现文字从左到右依次滚动的效果,关键在于下面两点:
-
设置父级容器的样式,当文字超出时,藏超出容器宽度的部分
-
动画
animation
的实现,通过@keyframes
实现一个从左到右滚动的动画效果
示例代码如下所示:
<div class="scroll-container"><span class="scroll-text">这里是需要滚动的文本内容</span>
</div>
<style>.scroll-container {width: 100%;overflow: hidden;}.scroll-text {white-space: nowrap;animation: scrollRight 5s linear infinite;display: inline-block;}@keyframes scrollRight {0% {transform: translateX(0);}100% {transform: translateX(-100%);}}
</style>
在上面的 CSS 样式中:
-
scroll-container
元素设置了overflow: hidden;
,用来隐藏超出容器宽度的部分。 -
scroll-text
元素使用white-space: nowrap;
来防止文字换行,display: inline-block;
让文本水平排列。 -
animation
属性定义了一个名为scrollRight
的动画,持续时间为 5 秒,线性匀速运动,无限循环。 -
@keyframes
定义了一个从左到右滚动的动画效果:从初始位置(translateX(0)
)到-100%
的水平偏移,实现文字从左到右滚动。
在必要时,也可以使用 JavaScript 控制动画的开始、暂停和重新开始。例如,可以通过 JavaScript 动态添加或移除动画类名来控制滚动效果的启停。
const scrollText = document.querySelector(".scroll-text");// 暂停滚动
function pauseScroll() {scrollText.style.animationPlayState = "paused";
}// 重新开始滚动
function resumeScroll() {scrollText.style.animationPlayState = "running";
}
通过上述代码的编写,即可实现文字从左到右依次滚动的效果。当页面加载时,文字将开始滚动;在需要暂停或重新开始时,可通过 JavaScript 来实现相应的操作。
四. 完整示例分析
1. 基本实现原理分析
-
首先通过 JavaScript 获取文本容器和文本内容元素。
-
判断文本内容的宽度是否超出容器的宽度,如果超出则添加滚动样式,否则移除滚动样式。
-
CSS 样式定义了一个
marquee
动画,使文本内容在容器内水平滚动显示。动画从右侧向左侧滚动,持续时间为 5 秒,速度线性,无限循环。 -
添加
white-space: nowrap;
样式确保文本内容不换行,实现水平滚动效果。 -
使用
overflow: hidden;
样式来隐藏超出容器的文本内容,实现跑马灯效果。
2. HTML 结构
<div class="marquee-container"><div class="marquee-text">这是一段需要滚动显示的文本内容~</div>
</div>
3. CSS 样式
.marquee-container {width: 200px; /* 容器宽度 */overflow: hidden; /* 内容超出时隐藏 */
}.marquee-text {white-space: nowrap; /* 内容不换行 */display: inline-block;
}.marquee-text-animation {animation: marquee 5s linear infinite; /* 滚动动画,时间可根据需要调整 */
}@keyframes marquee {0% {transform: translateX(100%);}100% {transform: translateX(-100%);}
}
4. JavaScript 实现
// 获取文本容器和文本内容元素
const container = document.querySelector(".marquee-container");
const text = document.querySelector(".marquee-text");// 判断文本内容是否超出容器宽度
if (text.getBoundingClientRect().width > container.clientWidth) {text.classList.add("marquee-text-animation"); // 添加滚动样式
} else {text.classList.remove("marquee-text-animation"); // 移除滚动样式
}
通过以上实现原理和示例代码,可以实现一个简单的文字跑马灯组件,具体的演示效果如下图所示,同时你也可以根据实际需要对样式和滚动效果进行调整。
当文本内容宽度未超出容器宽度时,文本内容保持静态显示即可。
当文本内容宽度超出容器宽度时,文本会自动滚动显示;
五. 总结
在本文中,我们详细分析了如何实现文字跑马灯效果,通过判断文字内容是否超出容器,进而实现自动滚动的功能,为网站添加了一个引人注目的动画效果。下面我来进行总结一下,实现文字滚动效果有以下几个要点:
-
判断文字的宽度是否超出:使用
el.getBoundingClientRect().width
API 获取文字的宽度,使用el.clientWidth
API 获取容器的宽度,当el.getBoundingClientRect().width > el.clientWidth
,触发文字滚动。 -
实现文字滚动动画:使用
transform
动画实现文字滚动效果。
文字跑马灯作为一种常见的动画效果,可以吸引用户的注意力。当然,本文只是在实现方式及实现原理上进行详细分析,你可以在了解这些之后对其进行更加具体的改造,比如动画效果、文字背景、上下滚动、操作暂停等等。
希望通过本文的学习,可以让你对文字跑马灯有了更深入的理解!
如果您感觉文章还不错,点个赞再走吧!