Racoon
Racoon

Reputation: 1011

Chrome Extension -> ExecuteScript: function call doesn' work

He is my manifest.json:

{
  "name": "Page Redder",
  "description": "Make the current page red",
  "version": "2.0",
  "permissions": [
    "activeTab","*://*/*"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "browser_action": {
    "default_icon" : "icon.png",
    "default_title": "Make this page red"
  },
  "manifest_version": 2
}

Here is background.js that works (the page becomes red):

chrome.browserAction.onClicked.addListener(function(tab) {

   chrome.tabs.executeScript(null, {code:'document.body.style.backgroundColor="red";'} );


});

If I change background.js in the following way, it fails to work:

function changeColor() {
    document.body.style.backgroundColor="red";

}

chrome.browserAction.onClicked.addListener(function(tab) {

   chrome.tabs.executeScript(null, {code:';'}, function() {
      changeColor();
   });

});

Chrome build: 38.0.2125.111

The question: what am I doing wrong here? Why calling a function in executeScript doesn't work?

Thanks, Racoon

Upvotes: 0

Views: 2452

Answers (1)

Xan
Xan

Reputation: 77523

You are not calling a function in executeScript.

You are calling the function in its callback, that runs in the original (background) page. It's a function describing "what to do when executeScript finishes", not the code to run.

The code that actually runs in the page you're injecting code to is ";" (which obviously does nothing).

You can run a function defined in your code with executeScript by properly converting it into a string. But note that it will not have any access to variables defined outside the function.


I think what you're trying to do is to make the code accept a parameter (color). Instead of crafting custom code each time, you should consider using Messaging to pass a command.

Example: add a file content.js with the following:

// Include guard: only execute once
if (!injected) {
  injected = true;
  init();
}

function init() {
  // Get ready to receive a command
  chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if(message.action == "colorBackground") {
      document.body.style.backgroundColor = message.color;
    }
  });
}

And in your background, you can do this:

chrome.tabs.executeScript(null, {file: "content.js"}, function() {
  // File executed, it's ready for the message
  chrome.tabs.sendMessage(null, { action: "backgroundColor", color: "green" });
}

Upvotes: 1

Related Questions