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 屬性中,因此較難維護;如果內容安全政策(Content Security Policy)禁止行內事件處理函式,也可能與政策衝突。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

<!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。停止時也要恢復元素的顯示狀態,避免計時器在元素隱藏期間結束後,重要文字一直無法顯示。

無障礙考量與替代做法

閃爍可能打斷閱讀,也可能讓某些人感到不適。請避免快速閃爍,不要只用閃爍來傳達重要資訊,並提供明確的停止方式。可以考慮靜態強調、短暫改變顏色,或只播放一次淡入淡出,看看是否能用較少動態傳達相同訊息。選擇動畫效果時,請尊重使用者減少動態效果的偏好,並確保停用動態效果後,重要文字仍然可見。對於一般狀態訊息,使用固定標籤或清楚標示的更新,通常比反覆閃爍更容易理解。