iT邦幫忙

2

從零打造輔大課表神器:Chrome Extension 開發實戰 30 天 - Day 10

  • 分享至 

  • xImage
  •  

Day 10:Chrome Extension 實作篇 - Popup 按鈕事件處理

🎯 系列目標:用 30 天時間,從零開始打造一個專屬輔大學生的課表生成 Chrome 擴充功能

👨‍💻 作者:輔大智慧資安 412580084

📅 Day 10:Chrome Extension 實作篇 - Popup 按鈕事件處理

🛠️ 讓按鈕真正動起來

昨天我們建立了 popup.js 的基礎架構,今天我們要讓按鈕真正具備功能!我們將學習如何處理按鈕點擊事件,並提供使用者回饋。

📋 學習目標

今天我們要完成:

  1. 🔘 實作按鈕點擊事件處理
  2. 📊 動態更新狀態顯示
  3. 🔄 防止重複點擊機制

🔘 實作按鈕點擊事件處理

1.1 生成課表按鈕處理

我們將要對生成課表按鈕添加重複點擊禁用的功能:

// 處理生成課表按鈕點擊
function handleGenerateClick() {
  console.log('🔘 生成課表按鈕被點擊');
  
  // 顯示載入狀態
  showStatus('正在準備生成課表...', 'info');
  
  // 禁用按鈕防止重複點擊
  const generateButton = document.getElementById('generateButton');
  generateButton.disabled = true;
  generateButton.textContent = '⏳ 處理中...';
  
  // 模擬處理過程(3秒後完成)
  setTimeout(() => {
    // 恢復按鈕狀態
    generateButton.disabled = false;
    generateButton.textContent = '📊 開始生成課表';
    
    // 顯示成功訊息
    showStatus('課表生成成功!', 'success');
    
    console.log('✅ 課表生成完成');
  }, 3000);
}

1.2 設定按鈕處理

設定按鈕也與生成課表按鈕一樣:

// 處理設定按鈕點擊
function handleSettingsClick() {
  console.log('🔘 設定按鈕被點擊');
  
  showStatus('正在載入設定...', 'info');
  
  // 模擬載入設定(2秒後完成)
  setTimeout(() => {
    showStatus('設定:自動儲存已開啟', 'success');
    
    // 3秒後回到準備狀態
    setTimeout(() => {
      showStatus('準備就緒', 'success');
    }, 3000);
  }, 2000);
}

📋 重要概念:setTimeout

  • setTimeout:延遲執行函數
  • 第一個參數:要執行的函數
  • 第二個參數:延遲時間(毫秒)
  • 用來模擬異步操作(如網路請求)

📊 動態更新狀態顯示

2.1 改進的狀態顯示函數

因為我們在按鈕添加了過度狀態 info,所以要在showStatus函數中將原本:

statusDiv.classList.remove('success', 'error');

修改成:

statusDiv.classList.remove('success', 'error', 'info');

然後再將原 if判斷式 改成:

statusDiv.classList.add(type);

2.2 添加Status載入動畫效果

function showLoadingStatus(message) {
  const statusDiv = document.getElementById('status');
  if (statusDiv) {
    statusDiv.innerHTML = `${message} <span class="loading">⏳</span>`;
    statusDiv.style.display = 'block';
    statusDiv.classList.remove('success', 'error');
    statusDiv.classList.add('info');
  }
}

2.3 更新 CSS 樣式

在 popup.html 的 <style> 區塊中添加新樣式:

.status.info {
  background-color: #e3f2fd;
  color: #1976d2;
}

.loading {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

🔄 防止重複點擊機制封裝

3.1 按鈕狀態管理

我們會發現生成與設定按鈕在禁用與啟用的程式碼有重複,所以應該要對按鈕狀態封裝以方便管理:

// 設定按鈕載入狀態
function setButtonLoading(buttonId, loadingText) {
  const button = document.getElementById(buttonId);
  if (button) {
    button.disabled = true;
    button.dataset.originalText = button.textContent;
    button.textContent = loadingText;
  }
}

// 恢復按鈕正常狀態
function resetButton(buttonId) {
  const button = document.getElementById(buttonId);
  if (button) {
    button.disabled = false;
    button.textContent = button.dataset.originalText || button.textContent;
  }
}

3.2 完整的事件處理函數

使用新的按鈕狀態管理重寫1.1 1.2事件處理使其更簡潔:

// 改進的生成課表按鈕處理
function handleGenerateClick() {
  console.log('🔘 生成課表按鈕被點擊');
  
  // 設定按鈕載入狀態
  setButtonLoading('generateButton', '⏳ 處理中...');
  
  // 顯示載入狀態
  showLoadingStatus('正在準備生成課表...');
  
  // 模擬處理過程
  setTimeout(() => {
    // 恢復按鈕狀態
    resetButton('generateButton');
    
    // 顯示成功訊息
    showStatus('課表生成成功!', 'success');
    
    console.log('✅ 課表生成完成');
  }, 3000);
}

// 改進的設定按鈕處理
function handleSettingsClick() {
  console.log('🔘 設定按鈕被點擊');
  
  setButtonLoading('settingsButton', '⏳ 載入中...');
  showLoadingStatus('正在載入設定...');
  
  setTimeout(() => {
    resetButton('settingsButton');
    showStatus('設定:自動儲存已開啟', 'success');
    
    setTimeout(() => {
      showStatus('準備就緒', 'success');
    }, 3000);
  }, 2000);
}

🧪 完整測試版本

測試步驟

  1. 更新 popup.js 檔案

    • 依照前面的步驟修改程式碼並保存
  2. 更新 popup.html 的 CSS

    • 添加新的樣式到 <style> 區塊
  3. 重新載入擴充功能
    0

  4. 測試按鈕功能

    • 點擊「開始生成課表」按鈕

    • 觀察按鈕變成「處理中...」並被禁用
      4

    • 等待 3 秒看到成功訊息
      5

  5. 檢查 Console 輸出

    • 查看詳細的 log 訊息為以下即成功
      6

📂 專案結構檢查

📁 fju-schedule-extension/
├── 📄 manifest.json     ← 擴充功能設定
├── 📄 background.js     ← 背景腳本
├── 📄 popup.html        ← 使用者介面(需更新 CSS)
└── 📄 popup.js          ← 彈出視窗邏輯(今天完成事件處理)

🔗 知識銜接:今天我們讓按鈕具備了真正的功能和使用者回饋,明天將學習如何讓 popup 與 background script 進行消息傳遞。

🎯 下集預告:Day 11 - Popup 與 Background 消息傳遞 📡


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言