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。停止时请恢复元素的可见状态,这样即使计时器在元素隐藏时结束,重要文本也不会一直被遮住。

无障碍与替代方案

闪烁可能打断阅读,也可能让一些人感到不适。避免快速闪烁,不要只用闪烁来传达重要信息,并提供明确的停止方式。可以考虑静态强调、短暂改变颜色或只淡入淡出一次;这些方式或许能以更少的动态效果传达同一信息。选择动画效果时,应尊重用户对减少动态效果的偏好,并确保关闭动态效果后重要文本仍然可见。对于常规状态消息,使用固定标签或清晰标示的更新,通常比反复闪烁更易理解。