将变量传递给新创建的选项卡

时间:2023-01-19 23:11:44

So I have a content script with an event that triggers a message to a "launching" script which I'm using to create a tab with a local html file and pass on the same message/variable to that tab. The tab should then load specified data based on the variable. It works as intended about 50% of the time, leading me to believe it's a synchronicity issue. I'm probably not going about this the right way, but it's the best I could work out on my own.

所以我有一个内容脚本,其中的事件触发了一个“启动”脚本的消息,我用它创建一个带有本地html文件的选项卡,并将相同的消息/变量传递给该选项卡。然后,选项卡应根据变量加载指定的数据。它大约50%的时间都按预期工作,这让我相信这是一个同步问题。我可能不会以正确的方式解决这个问题,但这是我能靠自己解决的最好方法。

Content Script (script.js):

内容脚本(script.js):

function openHistory(event) {
    var account = $(/*selector*/).html();
    chrome.runtime.sendMessage(account);
}

Launching Script (launch.js):

启动脚本(launch.js):

chrome.runtime.onMessage.addListener(function(account) {
    chrome.tabs.create({url: 'background.html'}, function(tab) {
        chrome.tabs.sendMessage(tab.id, account);
    });
});

HTML Script (background.js):

HTML脚本(background.js):

chrome.runtime.onMessage.addListener(function(account) {
    loadPage(account);
});

function loadPage(account) {
    chrome.storage.sync.get(account, function(data) {
        // Do stuff with DOM
    });
}

Manifest:

{
    "manifest_version": 2,

    "name": "Extension",
    "version": "1.0",

    "permissions": ["storage", "tabs"],

    "background": {
        "scripts": ["launch.js"],
        "persistent": false
    },

    "content_scripts": [{
            "js": ["jquery.js", "script.js"]
    }]
}

Update: I added "alert(chrome.runtime.lastError.message)" inside of the callback for tabs.sendMessage in launch.js, and whenever it doesn't work, I get "Could not establish connection. Receiving end does not exist."

更新:我在launch.js中为tabs.sendMessage的回调添加了“alert(chrome.runtime.lastError.message)”,每当它不起作用时,我得到“无法建立连接。接收端不存在“。

1 个解决方案

#1


5  

My guess would be that the callback used by chrome.tabs.create actually fires when the tab is ready, and not when its content has loaded. I can't quite tell because the documentation for this method doesn't say when the callback is fired.

我的猜测是,chrome.tabs.create使用的回调实际上在选项卡准备就绪时触发,而不是在其内容已加载时触发。我无法分辨,因为此方法的文档没有说明何时触发回调。

To get around this issue it may be best to have the newly opened background tab send a message back to its progenitor — as you know the launching script will already be up and running — to say "send me the details", at this point you then trigger chrome.tabs.sendMessage(tab.id, account);

要解决这个问题,最好让新打开的后台选项卡向其祖先发送一条消息 - 正如您所知,启动脚本已经启动并运行 - 说“向我发送详细信息”,此时您然后触发chrome.tabs.sendMessage(tab.id,account);

If that makes sense?

如果这有道理?

The following has not been tested and is just a guess as to what could work. Obviously with a closer look it might be possible to use the MessageSender to work out if the message has come from the background script or not — rather than using an object property. However I prefer to be specific about these things with my own code:

以下内容尚未经过测试,只是猜测可行的方法。显然,仔细观察可能会使用MessageSender来确定消息是否来自后台脚本 - 而不是使用对象属性。但是我更喜欢用我自己的代码来具体说明这些事情:

HTML Script (background.js):

HTML脚本(background.js):

chrome.runtime.sendMessage({from: 'background'});

Launching Script (launch.js):

启动脚本(launch.js):

chrome.runtime.onMessage.addListener(function(obj, sender) {
    if ( obj && obj.from == 'background' ) {
        chrome.tabs.sendMessage(sender.tab.id, obj);
    }
    else {
        chrome.tabs.create({url: 'background.html' });
    }
});

#1


5  

My guess would be that the callback used by chrome.tabs.create actually fires when the tab is ready, and not when its content has loaded. I can't quite tell because the documentation for this method doesn't say when the callback is fired.

我的猜测是,chrome.tabs.create使用的回调实际上在选项卡准备就绪时触发,而不是在其内容已加载时触发。我无法分辨,因为此方法的文档没有说明何时触发回调。

To get around this issue it may be best to have the newly opened background tab send a message back to its progenitor — as you know the launching script will already be up and running — to say "send me the details", at this point you then trigger chrome.tabs.sendMessage(tab.id, account);

要解决这个问题,最好让新打开的后台选项卡向其祖先发送一条消息 - 正如您所知,启动脚本已经启动并运行 - 说“向我发送详细信息”,此时您然后触发chrome.tabs.sendMessage(tab.id,account);

If that makes sense?

如果这有道理?

The following has not been tested and is just a guess as to what could work. Obviously with a closer look it might be possible to use the MessageSender to work out if the message has come from the background script or not — rather than using an object property. However I prefer to be specific about these things with my own code:

以下内容尚未经过测试,只是猜测可行的方法。显然,仔细观察可能会使用MessageSender来确定消息是否来自后台脚本 - 而不是使用对象属性。但是我更喜欢用我自己的代码来具体说明这些事情:

HTML Script (background.js):

HTML脚本(background.js):

chrome.runtime.sendMessage({from: 'background'});

Launching Script (launch.js):

启动脚本(launch.js):

chrome.runtime.onMessage.addListener(function(obj, sender) {
    if ( obj && obj.from == 'background' ) {
        chrome.tabs.sendMessage(sender.tab.id, obj);
    }
    else {
        chrome.tabs.create({url: 'background.html' });
    }
});