chrome分机调用特定函数

chrome extension call specific function

我有一个popup.js:

function registerButtonAction(tabId, button, action) {
    // clicking button will send a message to
    // content script in the same tab as the popup
    button.addEventListener('click', () => chrome.tabs.sendMessage(tabId, { [action]: true }));
}

function setupButtons(tabId) {
    // add click actions to each 3 buttons
    registerButtonAction(tabId, document.getElementById('start-btn'), 'startSearch');
    registerButtonAction(tabId, document.getElementById('deals-btn'), 'startDeals');
}

function injectStartSearchScript() {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        // Injects JavaScript code into a page
        // chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });

        // dd click handlers for buttons
        setupButtons(tabs[0].id);
    });
}

injectStartSearchScript()

// document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript);

我用它来将我的脚本注入我的 popup.html 中带有“start-btn”的页面。

这是我的main.js,其中包含我想在页面上调用的函数:

function pong() {
    // do something
}

function ping() {
// do something else
}

我的manifest.json:

{
    "manifest_version": 2,
    "name": "test app",
    "description": "test desc",
    "version": "1.0",
    "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
    },
    "permissions": ["tabs", "<all_urls>"],
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": ["main.js"]
        }
    ]
}

所以基本上我的设置是我有一个 popup.html,其中包含 3 个按钮,它们应该调用我的 main.js 中的功能之一,具体取决于我按下的按钮。

但我无法让它工作。目前,如果我在加载时直接在 main.js 内调用 pong() ,我只能进行至少一个函数调用。但是我需要在单击 popup.html.

中的按钮后调用其中一个函数

编辑: 据我所知,我已经更新了代码。非常抱歉,但我不明白还需要更改哪些内容才能实现您的建议。我的意思是怎么写才更正确。

编辑 2: 我删除了行 chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' }); 以及 document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript) 并添加了 injectStartSearchScript() 到 popup.js文件。你是这个意思吗?

带有解释的更新和完整示例(您快完成了!)

清单

您的清单看起来不错,无需更改。

此配置表示在每个选项卡中加载内容脚本。因此,甚至在弹出窗口打开之前,每个选项卡都会将“main.js”注入其中(恰好一次)。

popup.js

弹出脚本看起来不错,无需更改。

选项卡查找仍然是必要的,因为要将消息发送到特定选项卡,必须知道它的 ID。弹出窗口在当前 window 中查找当前活动的选项卡(与弹出窗口所在的相同)并设置按钮单击操作以向该选项卡发送消息。

main.js

此处需要进行小的改动

  • 确保注册 onMessage listener,如下例所示。
  • 注意条件:message.startSearchmessage.startDeals -- 这些必须匹配从弹出窗口发送的消息,即当弹出窗口发送内容为 {startDeals: true} 的消息时,if 条件是startDeals。它通过发送消息中的键匹配,如果键不匹配任何条件,消息将被忽略。
function pong() {
    // do something
    alert('Start!');
}

function ping() {
    // do something else
    alert('Deals!');
}

// register listener to receive messages
chrome.runtime.onMessage.addListener(message => {

    // what to do on each received message:
    if (message.startSearch) pong();
    else if (message.startDeals) ping();
});

// sanity check: content has loaded in the tab
console.log('content loaded');

当内容脚本被配置为在清单中注入时,与调试扩展(可能是其中一些调试问题的来源)有关的另一个注意事项,Chrome 将注入 main.js 到标签中,在一个单独的扩展上下文中。如果在此注入后,开发人员重新加载扩展(chrome://extensions 或其他工具中的圆形箭头),这将使选项卡中内容脚本的上下文无效。必须重新加载该选项卡才能重新激活内容脚本。这不是真实用户的问题,但在调试过程中确实会发生,所以在调试时仔细检查这不是问题的原因。