Javascript Chrome扩展:使用参数启动选项页

Javascript Chrome扩展:使用参数启动选项页,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我的分机有四个相关部分。选项卡中的注入脚本收集一些数据,该选项卡上的页面操作弹出窗口,在两者之间调解数据的背景脚本,以及选项页面。弹出窗口有一个按钮,打开选项页面 我想从弹出窗口打开选项页面,并给它一些数据,以便它可以显示与该选项卡相关的选项。下面是我为解决此问题而进行的精简和编辑尝试: popup.js var popup = (function() { var tabId; function openOptions() { port.postMessage

我的分机有四个相关部分。选项卡中的注入脚本收集一些数据,该选项卡上的页面操作弹出窗口,在两者之间调解数据的背景脚本,以及选项页面。弹出窗口有一个按钮,打开选项页面

我想从弹出窗口打开选项页面,并给它一些数据,以便它可以显示与该选项卡相关的选项。下面是我为解决此问题而进行的精简和编辑尝试:

popup.js

var popup = (function() {

    var tabId;

    function openOptions() {
        port.postMessage({
            action: 'openOptions',
            id: tabId
        });
    }

    function connectToBackground(tabs) {
        if (tabs.length > 0) {
            tabId = tabs[0].id;
            port = chrome.runtime.connect();
            port.postMessage({
                action: 'connect',
                id: tabId
            });
        }
    }

    return {
        initialize: function() {
            document.getElementById('settings').addEventListener('click', openOptions);
            chrome.tabs.query({active: true, currentWindow: true}, connectToBackground);
        }
    };
})();
popup.initialize();
var background = (function() {
    var tabs = {};
    return {
        onConnectInjected: function(port) {
            chrome.pageAction.show(port.sender.tab.id);

            port.onMessage.addListener(function(message, port) {
                if (message.action === 'connect') {
                    if (!tabs[port.sender.tab.id]) {
                        tabs[port.sender.tab.id] = {};
                    }
                    tabs[port.sender.tab.id].injected = port;
                    tabs[port.sender.tab.id].tabData = message.data;
                }
            });
            port.onDisconnect.addListener(function() {
                tabs[port.sender.tab.id].injected = null;
            });
        },
        onConnectPopup: function(port) {
            port.onMessage.addListener(function(message) {
                if (message.action === 'openOptions') {
                    chrome.runtime.openOptionsPage(function() {
                        for (let view of chrome.extension.getViews()) {
                            if (view.options) {
                                view.options.showOptionsRelevantToTab(tabs[message.id].tabData);
                            }
                        }
                    });
                } else if (message.action === 'connect') {
                    if (!tabs[message.id]) {
                        tabs[message.id] = {};
                    }
                    tabs[message.id].popup = port;
                    port.onDisconnect.addListener(function(port) {
                        tabs[message.id].popup = null;
                    });
                }
            });
        }
    };
})();
chrome.runtime.onConnectExternal.addListener(background.onConnectInjected);
chrome.runtime.onConnect.addListener(background.onConnectPopup);
var options = (function() {

    return {
        showDefaultOptions: function() {

        },
        showOptionsRelevantToTab: function(data) {

        }
    };
})();
options.showDefaultOptions();
background.js

var popup = (function() {

    var tabId;

    function openOptions() {
        port.postMessage({
            action: 'openOptions',
            id: tabId
        });
    }

    function connectToBackground(tabs) {
        if (tabs.length > 0) {
            tabId = tabs[0].id;
            port = chrome.runtime.connect();
            port.postMessage({
                action: 'connect',
                id: tabId
            });
        }
    }

    return {
        initialize: function() {
            document.getElementById('settings').addEventListener('click', openOptions);
            chrome.tabs.query({active: true, currentWindow: true}, connectToBackground);
        }
    };
})();
popup.initialize();
var background = (function() {
    var tabs = {};
    return {
        onConnectInjected: function(port) {
            chrome.pageAction.show(port.sender.tab.id);

            port.onMessage.addListener(function(message, port) {
                if (message.action === 'connect') {
                    if (!tabs[port.sender.tab.id]) {
                        tabs[port.sender.tab.id] = {};
                    }
                    tabs[port.sender.tab.id].injected = port;
                    tabs[port.sender.tab.id].tabData = message.data;
                }
            });
            port.onDisconnect.addListener(function() {
                tabs[port.sender.tab.id].injected = null;
            });
        },
        onConnectPopup: function(port) {
            port.onMessage.addListener(function(message) {
                if (message.action === 'openOptions') {
                    chrome.runtime.openOptionsPage(function() {
                        for (let view of chrome.extension.getViews()) {
                            if (view.options) {
                                view.options.showOptionsRelevantToTab(tabs[message.id].tabData);
                            }
                        }
                    });
                } else if (message.action === 'connect') {
                    if (!tabs[message.id]) {
                        tabs[message.id] = {};
                    }
                    tabs[message.id].popup = port;
                    port.onDisconnect.addListener(function(port) {
                        tabs[message.id].popup = null;
                    });
                }
            });
        }
    };
})();
chrome.runtime.onConnectExternal.addListener(background.onConnectInjected);
chrome.runtime.onConnect.addListener(background.onConnectPopup);
var options = (function() {

    return {
        showDefaultOptions: function() {

        },
        showOptionsRelevantToTab: function(data) {

        }
    };
})();
options.showDefaultOptions();
options.js

var popup = (function() {

    var tabId;

    function openOptions() {
        port.postMessage({
            action: 'openOptions',
            id: tabId
        });
    }

    function connectToBackground(tabs) {
        if (tabs.length > 0) {
            tabId = tabs[0].id;
            port = chrome.runtime.connect();
            port.postMessage({
                action: 'connect',
                id: tabId
            });
        }
    }

    return {
        initialize: function() {
            document.getElementById('settings').addEventListener('click', openOptions);
            chrome.tabs.query({active: true, currentWindow: true}, connectToBackground);
        }
    };
})();
popup.initialize();
var background = (function() {
    var tabs = {};
    return {
        onConnectInjected: function(port) {
            chrome.pageAction.show(port.sender.tab.id);

            port.onMessage.addListener(function(message, port) {
                if (message.action === 'connect') {
                    if (!tabs[port.sender.tab.id]) {
                        tabs[port.sender.tab.id] = {};
                    }
                    tabs[port.sender.tab.id].injected = port;
                    tabs[port.sender.tab.id].tabData = message.data;
                }
            });
            port.onDisconnect.addListener(function() {
                tabs[port.sender.tab.id].injected = null;
            });
        },
        onConnectPopup: function(port) {
            port.onMessage.addListener(function(message) {
                if (message.action === 'openOptions') {
                    chrome.runtime.openOptionsPage(function() {
                        for (let view of chrome.extension.getViews()) {
                            if (view.options) {
                                view.options.showOptionsRelevantToTab(tabs[message.id].tabData);
                            }
                        }
                    });
                } else if (message.action === 'connect') {
                    if (!tabs[message.id]) {
                        tabs[message.id] = {};
                    }
                    tabs[message.id].popup = port;
                    port.onDisconnect.addListener(function(port) {
                        tabs[message.id].popup = null;
                    });
                }
            });
        }
    };
})();
chrome.runtime.onConnectExternal.addListener(background.onConnectInjected);
chrome.runtime.onConnect.addListener(background.onConnectPopup);
var options = (function() {

    return {
        showDefaultOptions: function() {

        },
        showOptionsRelevantToTab: function(data) {

        }
    };
})();
options.showDefaultOptions();
神奇的事情应该发生在background.js中的chrome.runtime.openoptions页面的回调中。据我所知,当选项页面成功打开时,会调用此回调,但
chrome.extension.getViews()
仅返回背景视图(奇怪的是,返回弹出视图)

我曾尝试直接从弹出窗口打开选项页面,但由于选项是在另一个选项卡中打开的,弹出窗口会失去焦点并关闭,因此回调永远不会触发。我还探索了将消息从选项页面发送到后台脚本,但是background.js无法确定是哪个选项卡生成了选项页面

我还测试了在options.js中调用getViews,它实际上返回了弹出窗口(这反过来可以提供数据),但我不能确定这是否一致,因为弹出窗口同时存在

同样,background.js如何在创建时获取选项页的窗口对象,以便它可以为其提供相关数据,或者,让settings.js知道是哪个选项卡创建了它,以便它可以从background.js获取相关数据。如果我不需要为此添加“选项卡”权限,我更愿意这样做


感谢阅读:)

解决此问题的一种方法是让选项页面调用后台页面以获取相关页面数据。它看起来像这样:

// options.js init code:
chrome.runtime.sendMessage({action: "getOptionsData"}, (response) => {
  // Now that you have the response, you can set your settings and then make the page visible
});
在background.js中,您需要处理这个问题。最简单的方法是保存在
openOptions
处理程序中设置的全局变量
optionstate
,然后在
getOptionsData

这不应该是一个问题,因为在您的示例中,多个选项卡不应该打开选项

e、 g


这肯定行得通。我必须将其设置为“读取一次”,以便在下次“选项”打开时,通过右键单击另一个选项卡中的页面操作将其设置为空,从而显示默认选项。从弹出窗口打开选项,它将显示相关数据。但是,如果您将选项保持打开状态,来自其他选项卡的下一次调用将仅将焦点切换到包含旧数据的“选项”页面。通过侦听“选项”页面窗口上的“焦点”事件,修复了上述问题。@当用户再次单击“选项”页面上的选项卡时,焦点事件也会发生。也可以从右上角的关联菜单打开“选项”页。您如何知道用户是否只是单击选项选项卡并从上下文菜单中调用if?