HOWTO · JavaScript
在 JavaScript 中闪烁文本
本文将介绍如何通过窗口对象加载函数、onload 属性和使用 JavaScript 的 jQuery 约定来执行文本闪烁。
本页内容
闪烁文本可以吸引注意力,但也可能分散读者的注意力。如果这种效果适合你的页面,可以用 JavaScript 定时切换元素的可见状态。下面的示例展示了三种选择定时器启动时机的方法:整个页面加载完成后、通过 HTML onload 属性启动,或在 jQuery 指示 DOM 已就绪时启动。前两种方法会等待页面的加载事件;jQuery ready() 不会等待图像和其他资源加载完成。
使用 window 加载事件
当文档及其依赖资源(例如图像)加载完成后,window 加载事件就会触发。如果你希望效果只在整个页面准备就绪后才开始,可以为该事件注册监听器。下面这个独立的浏览器页面还会保存间隔计时器 ID,以便通过按钮停止效果。
本节中的代码以及显示的标签或输出仍为英文。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blink text after page load</title>
</head>
<body>
<p id="notice">Service is available</p>
<button id="stop" type="button">Stop blinking</button>
<script>
const notice = document.querySelector('#notice');
let blinkInterval;
window.addEventListener('load', () => {
blinkInterval = window.setInterval(() => {
notice.hidden = !notice.hidden;
}, 700);
});
document.querySelector('#stop').addEventListener('click', () => {
window.clearInterval(blinkInterval);
notice.hidden = false;
});
</script>
</body>
</html>
回调函数每隔 700 毫秒切换一次元素的 hidden 状态。这个延迟表示定时器安排回调的最短间隔,并不保证每次回调都能准时执行。停止按钮会清除重复计时器,并再次显示消息。对于较大的页面,建议使用 addEventListener,而不是给 window.onload 赋值,因为赋值可能会替换其他代码注册的处理函数。
使用 onload 属性
body 的 onload 属性也可以在页面加载事件触发后启动效果。页面加载完成时,它会调用一个命名函数。这种方法的触发时机与上面的 window 监听器相近,但它把 JavaScript 写在 HTML 属性中,因此较难维护;如果内容安全策略禁止内联处理函数,也可能与策略冲突。
本节中的代码以及显示的标签或输出仍为英文。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blink text with onload</title>
</head>
<body onload="startBlink()">
<p id="notice">Service is available</p>
<button type="button" onclick="stopBlink()">Stop blinking</button>
<script>
let blinkInterval;
function startBlink() {
const notice = document.querySelector('#notice');
blinkInterval = window.setInterval(() => {
notice.hidden = !notice.hidden;
}, 700);
}
function stopBlink() {
window.clearInterval(blinkInterval);
document.querySelector('#notice').hidden = false;
}
</script>
</body>
</html>
如果你要维护的小型示例已经使用内联处理函数,可以采用这种写法。在应用程序代码中,最好在脚本里注册监听器,让行为逻辑与标记分开。停止处理函数会清除由 startBlink() 启动的同一个间隔计时器。
使用 jQuery ready()
如果页面已经使用 jQuery,$(document).ready() 会在 HTML 文档解析完成、可以操作 DOM 时运行。它不会等待所有图像或其他页面资源加载完成;如果必须先等这些资源加载完毕,请使用 window 加载事件。jQuery 是可选依赖;此示例假定它已在后续脚本运行前加载。
本节中的代码以及显示的标签或输出仍为英文。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blink text with jQuery</title>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>
<p id="notice">Service is available</p>
<button id="stop" type="button">Stop blinking</button>
<script>
$(document).ready(function () {
const $notice = $('#notice');
const blinkInterval = window.setInterval(function () {
$notice.toggle();
}, 700);
$('#stop').on('click', function () {
window.clearInterval(blinkInterval);
$notice.show();
});
});
</script>
</body>
</html>
此时 DOM 已经存在,因此回调函数可以安全地选取段落。.toggle() 会切换元素的显示状态。如果页面可以使用上面展示的原生 DOM API,就不必仅为这个小效果引入 jQuery。
控制间隔并停止效果
setInterval(callback, delay) 会返回一个间隔计时器 ID。请保存该 ID,并在用户停止效果或组件被移除时将它传给 clearInterval。如果没有先清除已有计时器就再次启动计时器,多个计时器可能会重叠。请根据消息选择合适的延迟,并记住浏览器在标签页处于非活动状态时可能会延后执行任务。
提供的独立 JavaScript 示例已成功运行,且没有产生标准输出。它使用一个简单的元素对象和计时器桩,因此可以在不使用浏览器的情况下逐步调用回调。示例演示了如何切换可见状态并清理计时器;要操作真实网页元素,请使用上面的 HTML 示例之一。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
const notice = { style: { visibility: 'visible' } };
let tick;
let nextId = 0;
function startBlink(element) {
return setIntervalStub(() => {
element.style.visibility =
element.style.visibility === 'hidden' ? 'visible' : 'hidden';
}, 700);
}
function setIntervalStub(callback, delay) {
tick = callback;
return ++nextId;
}
function clearIntervalStub(id) {
if (id === nextId) tick = null;
}
const intervalId = startBlink(notice);
tick();
clearIntervalStub(intervalId);
在浏览器实现中,可以像前面的页面一样,将桩替换为 window.setInterval 和 window.clearInterval。停止时请恢复元素的可见状态,这样即使计时器在元素隐藏时结束,重要文本也不会一直被遮住。
无障碍与替代方案
闪烁可能打断阅读,也可能让一些人感到不适。避免快速闪烁,不要只用闪烁来传达重要信息,并提供明确的停止方式。可以考虑静态强调、短暂改变颜色或只淡入淡出一次;这些方式或许能以更少的动态效果传达同一信息。选择动画效果时,应尊重用户对减少动态效果的偏好,并确保关闭动态效果后重要文本仍然可见。对于常规状态消息,使用固定标签或清晰标示的更新,通常比反复闪烁更易理解。