admin管理员组

文章数量:1394146

I am writing an extension for Google Chrome and I am trying to add content in my current page when the user clicks on the add-on icon.

I would like to add the possibility to enable/disable the extension and to show/hide my injected content for every page.

manifest.json

"content_scripts": [
  {
    "matches": [
      "http://*/*",
      "https://*/*"
    ],
    "css": ["css/style.css"],
    "js": [
      "js/content.js"
    ]
  }
]

I do not see how to add content only for the page where the icon has clicked because with that, every page has the script.

I also tried something with the background script without success.

Do you have any ideas?

Thanks!

I am writing an extension for Google Chrome and I am trying to add content in my current page when the user clicks on the add-on icon.

I would like to add the possibility to enable/disable the extension and to show/hide my injected content for every page.

manifest.json

"content_scripts": [
  {
    "matches": [
      "http://*/*",
      "https://*/*"
    ],
    "css": ["css/style.css"],
    "js": [
      "js/content.js"
    ]
  }
]

I do not see how to add content only for the page where the icon has clicked because with that, every page has the script.

I also tried something with the background script without success.

Do you have any ideas?

Thanks!

Share Improve this question asked Aug 23, 2016 at 14:21 vermotrvermotr 7032 gold badges11 silver badges22 bronze badges 6
  • Is the icon being added to the page, or do you mean the extension icon that you see in the browser toolbar? – Reinstate Monica Cellio Commented Aug 23, 2016 at 14:31
  • I thought of the browser toolbar. – vermotr Commented Aug 23, 2016 at 14:36
  • Then you need to include the script at all times but only call whatever function you want to run, when the button is clicked. You don't conditionally include something - you always include it. – Reinstate Monica Cellio Commented Aug 23, 2016 at 14:37
  • There's no need to include the content script on all pages. It's a bad practice. The official Page Redder sample extension does exactly what you want. This collection has many other useful examples. In your case you'll need file: "js/content.js" instead of code: "...." used in Page Redder. – woxxom Commented Aug 23, 2016 at 14:39
  • Ok, thanks, I will take a look at this sample. I do not like the idea to include the content script all times, but if it is the only solution… – vermotr Commented Aug 23, 2016 at 14:42
 |  Show 1 more ment

3 Answers 3

Reset to default 4

I had built the same feature for my chrome extension. This will create an on/off switch / toggle (so many names when searching google to solve this :) ) I use the massaging between app and content script in the following method:

manifest

inserting my content script on all page (hover.js) and running my extension script (background.js)

....
"browser_action": {
    "default_icon": {
      "19": "icons/icon-active.png"
    }
  },
"content_scripts": [ 
{ 
  "matches": ["<all_urls>"], 
  "css": ["css/hover.css"], 
  "js": ["js/hover.js"] 
} 
],
"background" : { "scripts": ["js/background.js"] },
....

background.js

Here we are preparing the background script (which run on all chrome windows) to send and receive extension status

    // start extension as active
var status = true;

// set toggle of extension on browser action click and notify content script
chrome.browserAction.onClicked.addListener(function(tabs) {
  if (status == 'true'){
    status = false;
    chrome.browserAction.setIcon({path: "icons/16x16.png"});
  } 
  else{
    status = true;
    chrome.browserAction.setIcon({path: "icons/icon-active.png"});
  }
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {status: status});
  });
});

// check status on tab update and notify content script
chrome.tabs.onActivated.addListener(function() {
  if (status == 'true'){
    chrome.browserAction.setIcon({path: "icons/icon-active.png"});
  } 
  else{
    chrome.browserAction.setIcon({path: "icons/16x16.png"});
  }
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {status: status});
  });
});

//send extension status on request
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.status == "getStatus")
      sendResponse({status: status});
});

As you can see there are 3 functions:

  1. change the status on browser action button click.

  2. check status when you move to a different tab and notify content script (each tab has it's own "instance" of content script so disabling in one tab might still be active in another tab).

  3. send response of the status on request from content script.

content script

// check extension status
chrome.runtime.sendMessage({status: "getStatus"}, function(response) {
    if (response.status == 'true'){
        // check elements mouse is hover
        document.addEventListener("mouseover", setLink, true);
    }
    else{
        document.removeEventListener("mouseover", setLink, true);
    }
});

// wait for massage from background script
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.status == 'true'){
        // check elements mouse is hover
        document.addEventListener("mouseover", setLink, true);
    }
    else{
        document.removeEventListener("mouseover", setLink, true);
    }
});

Each content script should first check the status of the extension by sending massage to the background script and recieve a status update.

Also, if we turn the extension off in one tab, when we change tabs we will notify the content script of the change.

I'm sure that this can be done even better in terms of scripting but i hope it will help...

You should be achieve to do this using chrome.tabs.executeScript and chrome.tabs.insertCSS. Full example:

Background.js

chrome.browserAction.onClicked.addListener(function (tab) {
    chrome.tabs.insertCSS(tab.id, {file: "content_style.css"});
    chrome.tabs.executeScript(tab.id, {file: "content_script.js"});
});

Manifest.json

{
  "name": "Inject js and CSS",
  "version": "1",
  "manifest_version": 2,
  "browser_action": {
    "default_icon": {
      "16": "icon16.png",
      "19": "icon19.png",
      "32": "icon32.png",
      "38": "icon38.png"
    }
  },
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "permissions": [
    "activeTab"
  ]
}

Edit: Updated to use activeTab, event page and new icon sizes.

What do you think about that?

manifest.json

{
  "manifest_version": 2,

  "name": "Extension",
  "description": "My extension",
  "version": "0.1",

  "icons": {
    "16": "icons/icon_16.png",
    "48": "icons/icon_48.png",
    "128": "icons/icon_128.png"
  },

  "browser_action": {
    "default_title": "Extension",
    "default_icon": "icons/icon_16_disabled.png"
  },

  "background": {
    "scripts": ["js/background.js"],
    "persistent": true
  },

  "permissions": [
    "activeTab",
    "tabs"
  ]
}

background.js

var activedTab = {};
var injectedTab = {};

chrome.browserAction.onClicked.addListener(function(tab) {
  if (typeof activedTab[tab.id] === 'undefined') {
    activedTab[tab.id] = true;
    chrome.tabs.insertCSS(tab.id, {file: 'style.css'});
    chrome.tabs.executeScript(tab.id, {file: 'js/content.js'});
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
  } else if (activedTab[tab.id]) {
    activedTab[tab.id] = false;
    chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
    if (injectedTab[tab.id]) {
      chrome.tabs.sendMessage(tab.id, {greeting: 'hide'});
    }
  } else {
    activedTab[tab.id] = true;
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
    if (injectedTab[tab.id]) {
      chrome.tabs.sendMessage(tab.id, {greeting: 'show'});
    }
  }
});

chrome.runtime.onMessage.addListener(function(request, sender) {
  switch (request.greeting) {
    case 'content_injected':
      injectedTab[sender.tab.id] = true;
      if (activedTab[sender.tab.id] == false) {
        chrome.tabs.sendMessage(sender.tab.id, {greeting: 'hide'});
      }
      break;
  }
});

chrome.tabs.onUpdated.addListener(function(tabId) {
  delete activedTab[tabId];
  chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
});

chrome.tabs.onActiveChanged.addListener(function(tabId) {
  if (activedTab[tabId]) {
    chrome.browserAction.setIcon({path: 'icons/icon_16.png'});
  } else {
    chrome.browserAction.setIcon({path: 'icons/icon_16_disabled.png'});
  }
});

content.js

console.log('loaded');
chrome.extension.sendMessage({greeting: 'content_injected'});

chrome.runtime.onMessage.addListener(function(request) {
  switch (request.greeting) {
    case 'show':
      console.log('show');
      break;
    case 'hide':
      console.log('hide');
      break;
  }
});

本文标签: javascriptChrome extension Add content (enabledisable icon)Stack Overflow