How to show Chrome Extension on certain domains?

2019-01-15 14:42发布

I'm writing my first Chrome Extension. I've used permission, but I'm seeing my button everywhere.

How can I only show the button on the addresses I'm writing the extension for?

3条回答
霸刀☆藐视天下
2楼-- · 2019-01-15 14:46

Although the answer from @Sorter works, it is not the best way to solve the problem.

First and foremost, it does not always work. If the page used history.pushState, the page action will disappear and not come back until you trigger the onUpdated or onHighlighted event again Chromium issue 231075.

Secondly, the method is inefficient, because it's triggered for every update of tab state on all pages.

The most efficient and reliable way to get a page action to appear on certain domains is to use the declarativeContent API. This is only available since Chrome 33. Before that, the webNavigation API was the most suitable API. The advantage of these API over the method using the tabs API is that you can safely use event pages, because you can declare URL filters. With these URL filters, the events will only be triggered if you navigate to a page that matches the URL filters. Consequently, your extension/event page will not be activated until really needed (= no wasted RAM or CPU).

Here's a minimal example (background.js) using the webNavigation API:

function onWebNav(details) {
    if (details.frameId === 0) {
        // Top-level frame
        chrome.pageAction.show(details.tabId);
    }
}
var filter = {
    url: [{
        hostEquals: 'example.com'
    }]
};
chrome.webNavigation.onCommitted.addListener(onWebNav, filter);
chrome.webNavigation.onHistoryStateUpdated.addListener(onWebNav, filter);

manifest.json:

{
    "name": "Name ",
    "version": "1",
    "manifest_version": 2,
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    },
    "page_action": {
        "default_title": "Only visible on stackoverflow.com"
    },
    "permissions": [
        "webNavigation"
    ]
}

If you target Chrome 33 and higher, then you can also use the declarativeContent API instead. Simply replace the "webNavigation" permission with "declarativeContent", and use the following background script (background.js):

chrome.runtime.onInstalled.addListener(function() {
    chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
        chrome.declarativeContent.onPageChanged.addRules([{
            conditions: [
                new chrome.declarativeContent.PageStateMatcher({
                    pageUrl: {
                        hostEquals: 'example.com'
                    }
                })
            ],
            actions: [new chrome.declarativeContent.ShowPageAction()]
        }]);
    });
});

In both examples, I used a UrlFilter that matches the example.com domain.

查看更多
Luminary・发光体
3楼-- · 2019-01-15 14:56

Create background.js which checks for updated and highlighted tab.

function checkForValidUrl(tabId, changeInfo, tab) {

   // If  'example.com' is the hostname for the tabs url.
   var a = document.createElement ('a');
   a.href = tab.url;
   if (a.hostname == "example.com") {
       // ... show the page action.
       chrome.pageAction.show(tabId);
   }
};

// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
//For highlighted tab as well
chrome.tabs.onHighlighted.addListener(checkForValidUrl);

Create popup.html and popup.js in the similar manner.

You can use the variables defined in background.js in content scripts (popup.js) with chrome.extension.getBackgroundPage().variableName

Here's the example extention download link.

For your reference and ease, here's the sample manifest.json file

 {
    "manifest_version": 2,
    "name": "Example Extension",
    "version": "1.0",

    "background": {
        "scripts": ["background.js"]
    },

    "page_action":{
        "default_icon": "images/icon_16.png",
        "default_popup": "popup.html",
        "default_title": "Title for the extension"
    },
    "permissions": [
        "tabs"
    ]
}
查看更多
Ridiculous、
4楼-- · 2019-01-15 15:05

An Updated Way:

I use the following with great success:

chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
    var url = info.url || tab.url;
    if(url && url.indexOf('example.com') > -1)
        chrome.pageAction.show(tabId);
    else
        chrome.pageAction.hide(tabId);
});
查看更多
登录 后发表回答