iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
佛心分享-SideProject30

從零開始改善工作之 Chrome Extension: MR 通知文字小工具系列 第 9

Day 9:使用 MutationObserver 解決動態載入的問題

  • 分享至 

  • xImage
  •  

昨天我們成功抓到標題了!
但是 Reviewer 卻沒有成功顯示...
https://ithelp.ithome.com.tw/upload/images/20250915/20153928qthIj48wcA.png

WHY

重新整理頁面我們會發現,Reviewer 這個區塊在 GitLab 載入後,需要再 Loading 一段時間才會完全顯示,而這就會讓我們 Content Script 在畫面剛載入進來頁面時抓不到我們想要的文字
https://ithelp.ithome.com.tw/upload/images/20250916/201539283h3l2toqY7.png

HOW

解決這個問題有幾個方法

  1. setTimeout 延遲執行
    說明:設定固定的等待時間,等一下再抓文字
    => 簡單,但難以確定網頁載入會用多少時間,還是可能抓不到

    setTimeout(() => {
       const reviewerEl = document.querySelector("[data-testid='reviewer'] div")
       console.log("Reviewer:", reviewerEl);
     }, 2000); // 延遲 2 秒
    
  2. 使用 MutationObserver
    說明:監聽 DOM 變化,等 reviewer 區塊出現再抓取。
    => MutationObserver 可以觀察只要 document.body 有子節點的變動,就匯檢查看看有沒有可不可以抓文字

     const targetNode = document.body; //要觀察的子節
     const config = { childList: true, subtree: true }; //observe 設定
    
     const callback = (mutationsList, observer) => {
         const reviewerEl = document.querySelector("[data-testid='reviewer'] div");
         if (reviewerEl) {
             console.log("Reviewer:", reviewerEl.innerText.trim());
             observer.disconnect(); // 抓到就停止監聽,避免浪費效能
         }
     };
    
     const observer = new MutationObserver(callback);
     observer.observe(targetNode, config);
    

    options 中我們有用到的屬性:

    參數 說明
    childList (Boolean)偵測子節點的更動
    subtree (Boolean)對其節點下所有延伸的節點進行觀察

    ※ Day 2 分享的一位作者有寫一篇詳細的介紹,可以去看看 → MutationObserver - DOM 宇宙的觀察者

為了我們 Extenstion 能正確抓到我們要的內容,所以我們使用 MutationObserver 來處理吧!

整合至 Content Script

  1. 因為我們希望能抓到內容,所以把抓取標題和 Reviewer 的文字,都放到 MutationObserver

    //content_script.js
    console.log("Content Script 已注入到 MR 頁面!");
    
    const targetNode = document.body;
    const config = { childList: true, subtree: true };
    
    const callback = (mutationsList, observer) => {
        const titleEl = document.querySelector(".title")
            || document.querySelector("[data-testid='title-content']")
            || document.querySelector("h1");
        const reviewerEl = document.querySelector("[data-testid='reviewer'] div");
        if (titleEl && reviewerEl) {
            console.log("MR 標題:", titleEl.innerText.trim());
            console.log("Reviewer:", reviewerEl.innerText.trim());
            observer.disconnect(); // 抓到就停止監聽,避免浪費效能
        }
    };
    
    const observer = new MutationObserver(callback);
    observer.observe(targetNode, config);
    

    這樣子我們就可以確保 Content Script 能抓到文字囉~
    接著就來實際測試一下吧!

    實際測試

    • 打開一個 GitLab Merge Request 頁面。
    • 在 MR 頁面開啟 F12 → Console
    • 就可以看到我們想要的標題和文字囉!
      https://ithelp.ithome.com.tw/upload/images/20250916/20153928GJBZEZnx0b.png

    參考來源


上一篇
Day 8:選取 GitLab Merge Request 中所需要的資訊
系列文
從零開始改善工作之 Chrome Extension: MR 通知文字小工具9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言