前言
在 Web 開發中,動態更新的 DOM 元素常因 AJAX 或前端框架渲染而改變,這些變化不一定會觸發傳統事件。若需要即時監控特定元素內容變化並同步更新到 Cookie,MutationObserver 是一個有效的解決方案。本文針對如何監聽 class 為 .am-cappa__name 的元素變化,並將其內容存入 Cookie 進行說明。
為何需要監聽 DOM 變化?
動態網頁中,元素內容可能透過非同步請求或前端框架更新,這些變化不會觸發像 click、input 等事件。若想在內容變更時執行特定邏輯(例如同步資料),MutationObserver 可監聽子節點或文字內容的變動,達成即時反應。
監聽 .am-cappa__name 並更新 Cookie 的核心邏輯
- 使用
MutationObserver監聽目標元素的子節點與文字變化:const observer = new MutationObserver(() => { saveCappaName(); }); - 透過
observer.observe()設定監聽選項,包含childList、characterData與subtree,確保所有子節點及文字變化都能被捕捉。 - 定義
saveCappaName()函式,取得.am-cappa__name元素的文字內容,並與上一次儲存的值比較,若不同則更新 Cookie:function saveCappaName() { let cappaElement = document.querySelector(".am-cappa__name"); if (cappaElement) { let cappaValue = cappaElement.innerText.trim(); if (cappaValue && cappaValue !== lastCappaValue) { document.cookie = "am_cappa_name=" + encodeURIComponent(cappaValue) + "; path=/; max-age=86400"; lastCappaValue = cappaValue; } } } - 初始時嘗試取得目標元素並啟動監聽,若元素尚未載入,使用
setTimeout每 500ms 重試,確保監聽能啟動。 - 為避免 MutationObserver 在某些情況下漏掉變化,額外使用
setInterval每 500ms 強制執行一次saveCappaName(),提高更新可靠性。
為何要存入 Cookie?
- 跨頁面存取:Cookie 可在不同頁面間共享資料,方便維持狀態。
- 持久化資料:設定
max-age=86400,資料可保存一天,使用者關閉瀏覽器後仍可讀取。 - 後端存取:伺服器可從 HTTP 請求中讀取 Cookie,做進一步處理或驗證。
實際應用與延伸
此技術適用於動態表單內容的即時保存、使用者偏好設定同步等場景。未來可結合 LocalStorage 或 IndexedDB 進行更複雜的資料管理,或搭配前端框架的狀態管理提升效能。
常見坑
- MutationObserver 監聽範圍設定不當可能漏掉變化,需包含
subtree。 - 監聽目標元素尚未載入時需重試,否則無法啟動監聽。
- Cookie 大小限制與安全性考量,敏感資料不宜存放。
完整程式碼
document.addEventListener("DOMContentLoaded", function () {
let lastCappaValue = ""; // 儲存上一次的值,避免重複存相同的值
function saveCappaName() {
let cappaElement = document.querySelector(".am-cappa__name");
if (cappaElement) {
let cappaValue = cappaElement.innerText.trim();
if (cappaValue && cappaValue !== lastCappaValue) {
document.cookie = "am_cappa_name=" + encodeURIComponent(cappaValue) + "; path=/; max-age=86400";
console.log("Cookie 更新成功: " + cappaValue);
lastCappaValue = cappaValue; // 更新最後的值
}
}
}
// 使用 MutationObserver 監聽 `.am-cappa__name` 是否變更
const observer = new MutationObserver(() => {
saveCappaName(); // 內容變更時,更新 Cookie
});
function startObserving() {
let targetElement = document.querySelector(".am-cappa__name");
if (targetElement) {
observer.observe(targetElement, { childList: true, characterData: true, subtree: true });
saveCappaName(); // 先存一次當前值
} else {
// 若元素還沒出現,每 500ms 檢查一次
setTimeout(startObserving, 500);
}
}
// 額外增加每 500ms 手動檢查一次
setInterval(() => {
saveCappaName();
}, 500);
startObserving(); // 啟動監聽
});