You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Chrome扩展DOM/URL变更时重新执行content.js脚本?

解决Chrome扩展在Facebook商务平台标签切换后按钮消失的问题

你的问题本质是Facebook商务平台是单页应用(SPA)——切换标签时不会刷新整个页面,只是动态更新DOM内容,而你的content.js默认只在页面首次加载时执行一次,所以切换回Campaigns标签后,新渲染的DOM元素没有被处理,按钮自然就消失了。下面给你一套完整的解决方案:

核心思路

我们需要做三件事:

  • 把按钮生成的核心逻辑封装成可重复调用的函数
  • 用MutationObserver监听DOM动态变化,自动触发逻辑
  • 让background脚本在标签切换/URL变化时通知content.js重新执行逻辑

代码修改步骤

1. 重构content.js:封装逻辑+监听DOM+响应消息

把按钮生成的代码抽成独立函数,同时添加DOM监听和消息监听:

// 封装核心按钮设置逻辑,方便重复调用
function setupButtons() {
    // 修改"Reporting Ends"文本
    const botme = $("_643l:contains('Reporting Ends')");
    botme.text("Add?");

    // 替换年份元素为按钮
    const year = new Date().getFullYear();
    const boxspot = $("_1b33:contains(" + year + ")");
    boxspot.replaceWith('<button class="open-dialog-btn">Bot me!</button><div id="dialog"></div>');

    // 用事件委托绑定点击(避免动态元素绑定失效)
    $(document).off('click', '.open-dialog-btn').on('click', '.open-dialog-btn', function() {
        const popup = window.open("", "popupWindow", "width=600, height=400, scrollbars=yes");
        $(popup.document.body).html("<textarea>It works!</textarea>");
    });
}

// 页面首次加载时执行
$(document).ready(function() {
    setupButtons();

    // 监听DOM变化:当Campaigns区域更新时重新生成按钮
    // 建议替换成更精确的父容器(比如Campaigns列表的容器),减少性能消耗
    const targetContainer = document.body;
    const observerConfig = { childList: true, subtree: true };

    const domObserver = new MutationObserver((mutations) => {
        // 检查目标元素是否存在,避免无意义触发
        if ($("_643l:contains('Reporting Ends')").length && $("_1b33:contains(" + new Date().getFullYear() + ")").length) {
            setupButtons();
        }
    });

    domObserver.observe(targetContainer, observerConfig);
});

// 监听background脚本发来的刷新指令
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.action === 'refreshButtons') {
        setupButtons();
        sendResponse({ status: "buttons refreshed" });
    }
});

2. 优化background.js:监听标签切换和URL变化

确保在两种场景下通知content.js:用户导航到Campaigns页面,或者从其他标签切换回Campaigns页面:

// 精准匹配Campaigns页面的URL
const campaignsUrlRegex = /^https?:\/\/(www\.)?business\.facebook\.(com|\w\w(\.\w\w)?)\/adsmanager\/manage\/campaigns.*$/;

// 监听标签URL更新(比如从其他页面导航到Campaigns)
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
    if (changeInfo.url && campaignsUrlRegex.test(changeInfo.url)) {
        chrome.tabs.sendMessage(tabId, { action: 'refreshButtons' });
    }
});

// 监听标签激活(切换到已经打开的Campaigns标签)
chrome.tabs.onActivated.addListener((activeInfo) => {
    chrome.tabs.get(activeInfo.tabId, (tab) => {
        if (campaignsUrlRegex.test(tab.url)) {
            chrome.tabs.sendMessage(activeInfo.tabId, { action: 'refreshButtons' });
        }
    });
});

// 保留原有的browser action点击逻辑
chrome.browserAction.onClicked.addListener((tab) => {
    chrome.tabs.sendMessage(tab.id, { action: "pageToSpeech" }, () => {});
});

3. 关键注意事项

  • 选择器稳定性:Facebook经常会修改页面的class名(比如_643l、_1b33),如果后续按钮消失,先检查这些选择器是否还能匹配到目标元素。
  • 监听范围优化:尽量找到Campaigns列表的具体父容器(比如通过浏览器开发者工具定位),替换掉document.body作为监听目标,减少不必要的DOM监听触发,提升性能。
  • 事件委托:用$(document).on('click', '.open-dialog-btn', ...)代替直接绑定按钮点击,因为动态生成的元素无法直接绑定事件,事件委托可以解决这个问题。

内容的提问来源于stack exchange,提问作者lob0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:55:31