3

我试图让 Chrome pageAction 图标出现,但它只是在页面加载时短暂闪烁然后消失。

然而,让我感到困惑的是,当我使用开发工具调试器并在 chrome.pageAction.show() 调用上设置断点时,它可以完美运行!这是我的 manifest.json:

{
    "manifest_version": 2,
    "name": "20130409-test",
    "description": "Page action icons don't work!",
    "version": "0.1",
    "icons": {"16": "icon16.png", "48": "icon48.png", "128": "icon128.png"},
    "background": {
        "scripts": ["background.js"],
        "persistent": true
    },
    "permissions": [
        "<all_urls>",
        "webRequest",
        "webRequestBlocking"
    ],
    "page_action": {
        "default_icon": {
            "19": "icon19.png",
            "38": "icon38.png"
        },
        "default_title": "Page action title here!"
    }
}

我的 background.js 页面是:

chrome.webRequest.onSendHeaders.addListener(
    function(details) {
        chrome.pageAction.show(details.tabId);
        chrome.pageAction.setTitle({
            "tabId": details.tabId,
            "title": "url=" + details.url
        });
    },
    {urls: ["<all_urls>"], types: ["main_frame"]},
    ["requestHeaders"]
);
4

1 回答 1

6

A page action which is bound to a specific tab is removed when the tab's page unloads.

chrome.webRequest.onSendHeaders当一个新的请求即将开始时触发。这意味着上一页仍在显示中。当您调用 时chrome.pageAction.show,会为当前页面激活页面操作,并在加载请求的页面后立即消失。

通过使用开发人员工具设置断点(或使用debugger;语句),chrome.pageAction.show可以充分延迟,并且页面动作在新页面加载后显示。

使用内容脚本chrome.tabs.onUpdated事件,除非您希望在发起请求后立即查看 URL。

方法一:内容脚本

内容脚本应仅在顶级框架中注入。最好尽快,这样用"run_at":"document_start"

// PART of manifest.json
"background": {
    "scripts": ["background.js"]
},
"content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["contentscript.js"],
    "run_at": "document_start",
    "all_frames": false
}], ...........

// Content script: contentscript.js
chrome.extension.sendMessage({type:'showPageAction'});

// Background page: background.js
chrome.extension.onMessage.addListener(function(message, sender) {
    if (message && message.type === 'showPageAction') {
        var tab = sender.tab;
        chrome.pageAction.show(tab.id);
        chrome.pageAction.setTitle({
            tabId: tab.id,
            title: 'url=' + tab.url
        });
    }
});

这种方法的缺点是它不适用于受限制的 URL。例如,您将看不到数据 URI、Chrome 网上商店等的页面操作。此问题不会出现在下一个方法中。

方法二:chrome.tabs.onUpdated

// background.js
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    chrome.pageAction.show(tabId);
    chrome.pageAction.setTitle({
        tabId: tab.id,
        title: 'url=' + tab.url
    });
});

注意:onUpdated每个选项卡加载都会多次调用。最初在 URL 更改时执行一次,然后为每个(顶级/子)框架执行两次。减少不必要的调用次数会很好chrome.pageAction,但没有直接的方法。
如果您只检查 的值changeInfo.url,则刷新页面时不会显示页面操作。

于 2013-04-10T09:00:27.890 回答