iT邦幫忙

0

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

  • 分享至 

  • xImage
  •  

Day 19:精確分頁狀態監聽

🔄 從基本控制到精確監聽

昨天我們學會了基本的分頁控制。今天要進一步處理「精確監聽」,確保在正確時機執行操作。

📋 學習目標

  1. 理解分頁載入階段
  2. 撰寫精確的狀態監聽函數
  3. 檢測頁面是否準備就緒
  4. 測試監聽的準確性
  5. 實作自動頁面跳轉

🎯 分頁載入階段

常見的載入狀態:

  • loading:DOM 建構中
  • interactive:DOM 載入完成,但資源未全載入
  • complete:頁面與資源皆完成

若操作過早,可能會遇到資料不完整問題,因此需要更精確的監聽。

精確監聽函數範例

function waitForTabCompleteLoad(tabId, timeout = 20000) {
  return new Promise((resolve, reject) => {
    let isResolved = false;
    const timeoutId = setTimeout(() => {
      if (!isResolved) {
        isResolved = true;
        reject(new Error('分頁載入超時'));
      }
    }, timeout);

    const stateListener = (updatedTabId, changeInfo, tab) => {
      if (updatedTabId !== tabId || isResolved) return;
      if (changeInfo.status === 'complete') {
        clearTimeout(timeoutId);
        chrome.tabs.onUpdated.removeListener(stateListener);
        isResolved = true;
        resolve({ tabId: tab.id, url: tab.url, title: tab.title });
      }
    };

    chrome.tabs.onUpdated.addListener(stateListener);
    chrome.tabs.get(tabId, (tab) => {
      if (!isResolved && tab.status === 'complete') {
        clearTimeout(timeoutId);
        chrome.tabs.onUpdated.removeListener(stateListener);
        isResolved = true;
        resolve({ tabId: tab.id, url: tab.url, title: tab.title });
      }
    });
  });
}

🔍 頁面就緒檢測

除了狀態監聽,也要確認必要元素是否存在:

function checkPageReady(tabId) {
  return new Promise((resolve) => {
    chrome.scripting.executeScript({
      target: { tabId },
      function: () => {
        const ready = document.querySelector('#GV_NewSellist') !== null;
        return { ready, title: document.title, url: location.href };
      }
    }, (results) => {
      resolve(results?.[0]?.result || { ready: true });
    });
  });
}
function checkPageReady(tabId) {
  return new Promise((resolve) => {
    chrome.scripting.executeScript({
      target: { tabId },
      function: () => {
        const ready = document.querySelector('#GV_NewSellist') !== null;
        return { ready, title: document.title, url: location.href };
      }
    }, (results) => {
      resolve(results?.[0]?.result || { ready: true });
    });
  });
}

⏳ 等待頁面完全就緒

結合分頁狀態與元素檢查:

async function waitForPageFullyReady(tabId) {
  await waitForTabCompleteLoad(tabId);
  await new Promise(r => setTimeout(r, 3000)); // 保險等待
  return await checkPageReady(tabId);
}

🔄 流程整合

在課表生成流程中:

  1. 開啟課表頁面

  2. 等待完全就緒

  3. 提取資料或進行操作

  4. 查看 schedule.html 的日誌
    2


🎯 明日預告

明天我們將學習基礎資料提取架構設計


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

尚未有邦友留言

立即登入留言