iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
Modern Web

從 UI/UX 設計到前端實作:30 天打造專屬的任務學習計時器系列 第 15 篇

DAY 15|功能實作(三):UI 按鈕狀態切換與暫停/結束控制

  • 分享至 

  • xImage
  •  

前兩天的實作中,成功地讓計時器開始動起來,但當按下開始計時後,按鈕的UI卻沒有變化,今天就要來完成這一部分:點擊「開始」時動態隱藏/顯示按鈕,並實現「暫停/繼續」與「結束」功能。


步驟 1:使用 Bootstrap 5 類別切換介面

在切版時,針對計時中的按鈕(暫停/結束)使用了 Bootstrap 的 d-none (display: none) 先隱藏起來了。

因此當計時開始時,我們要把 #btn-start 加上 d-none 隱藏,並將包含暫停與結束按鈕的 #btn-group-active 移除 d-none 顯示出來:

html部分

<!-- 計時控制按鈕區塊 -->
  <div id="timer-controls" class="mb-3">
    <!-- 狀態 A:未計時(預設顯示) -->
    <button
      id="btn-start"
      type="button"
      class="btn btn-primary btn-lg px-4"
    >
      <i class="bi bi-play-fill me-1"></i>開始計時
    </button>

    <!-- 狀態 B:計時中(預設隱藏) -->
    <div id="btn-group-active" class="d-none">
      <button
        id="btn-pause"
        type="button"
        class="btn btn-warning btn-lg me-2"
      >
        <i class="bi bi-pause-fill me-1"></i>暫停
      </button>
      <button
        id="btn-stop"
        type="button"
        class="btn btn-danger btn-lg"
      >
        <i class="bi bi-stop-fill me-1"></i>結束
      </button>
    </div>
  </div>

js部分

function startTimer() {
  if (isRunning) return;

  isRunning = true;

  // UI 切換:隱藏「開始」,顯示「暫停 / 結束」按鈕組
  btnStart.classList.add('d-none');
  btnGroupActive.classList.remove('d-none');

  timerInterval = setInterval(() => {
    seconds++;
    timerDisplay.textContent = formatTime(seconds);
  }, 1000);
}

步驟 2:實作「暫停與繼續」二合一切換

同一個暫停按鈕,在計時中點擊會變為「繼續」,再次點擊又會恢復為「暫停」。可以利用 isRunning 狀態來做判斷:

// 暫停 / 繼續切換函式
function togglePauseTimer() {
  if (isRunning) {
    // 進入暫停狀態:清除定時器
    clearInterval(timerInterval);
    isRunning = false;

    // 更新 UI 樣式為「繼續」
    btnPause.innerHTML = '<i class="bi bi-play-fill me-1"></i>繼續';
    btnPause.classList.replace('btn-warning', 'btn-success');
  } else {
    // 恢復計時狀態:重新啟動定時器
    isRunning = true;

    // 更新 UI 樣式為「暫停」
    btnPause.innerHTML = '<i class="bi bi-pause-fill me-1"></i>暫停';
    btnPause.classList.replace('btn-success', 'btn-warning');

    timerInterval = setInterval(() => {
      seconds++;
      timerDisplay.textContent = formatTime(seconds);
    }, 1000);
  }
}

步驟 3:實作「結束計時」與狀態重置

按下「結束」時,必須徹底清空定時器、資料歸零,並把 UI 恢復成最初的樣子:

// 結束計時函式
function stopTimer() {
  // 1. 清除定時器與狀態重置
  clearInterval(timerInterval);
  timerInterval = null;
  isRunning = false;
  seconds = 0;

  // 2. 顯示文字與暫停按鈕樣式復原
  timerDisplay.textContent = '00:00:00';
  btnPause.innerHTML = '<i class="bi bi-pause-fill me-1"></i>暫停';
  btnPause.classList.replace('btn-success', 'btn-warning');

  // 3. UI 切換:隱藏暫停/結束組,顯示開始按鈕
  btnGroupActive.classList.add('d-none');
  btnStart.classList.remove('d-none');
}

// 監聽事件綁定
btnPause.addEventListener('click', togglePauseTimer);
btnStop.addEventListener('click', stopTimer);

(今日成果)
timer v-2


小結

經過這三天的拆解實作,我們從資料處理、非同步計時,到最後的 DOM 互動與 UI 狀態切換,打造出了一個功能齊備、體驗順暢的計時器核心模組。


上一篇
DAY 14|功能實作(二):setInterval 與計時核心邏輯
下一篇
DAY 16|功能實作(四):精確計時(Date.now())與 background 防休眠
系列文
從 UI/UX 設計到前端實作:30 天打造專屬的任務學習計時器 共 20 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言