昨天我們學會了基本的分頁控制。今天要進一步處理「精確監聽」,確保在正確時機執行操作。
常見的載入狀態:
若操作過早,可能會遇到資料不完整問題,因此需要更精確的監聽。
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);
}
在課表生成流程中:
開啟課表頁面
等待完全就緒
提取資料或進行操作
查看 schedule.html
的日誌
明天我們將學習基礎資料提取架構設計