Syed Daniyal Shah
Syed Daniyal Shah

Reputation: 303

Sending message to Content Script in Chrome Extension

I am trying to send a message from my background script to content script and failing at it.

Here is my code in background script :

    iterator=0;
    chrome.tabs.query({},function(tabs){
       for(var i=0; i<tabs.length; i=i+1){
            chrome.tabs.executeScript(tabs[i].id,{file: 'createBanner.js'});
       }
       for (var i=0; i<tabs.length; i=i+1){
         chrome.tabs.sendMessage(tabs[i].id,{
             action: "currentPicNumber",picNumber: iterator
         });
       }
    });

In my content script (createBanner.js) I have:

chrome.runtime.onMessage.addListener(function(request,response,sendResponse){
   if(request.action=="currentPicNumber"){
     console.log(request.picNumber.toString());
   }
});

When I run it the console does not show anything. I want to to be able to send messages back and forth in between createBanner.js and my background script.

Please help thank you

Upvotes: 0

Views: 288

Answers (2)

Xan
Xan

Reputation: 77591

chrome.tabs.executeScript is asynchronous. By the time sendMessage is called, the script is not yet ready to receive it.

You can specify a callback for executeScript, that will run only after injected JavaScript has been executed (i.e. handlers registered). In order for the clojure to work properly, I use a higher-order function messageCallback that returns a callback function.

So, your code will look like:

function messageCallback(tabId, picNumber){
    return function(){
        chrome.tabs.sendMessage(
            tabId,
            {action: "currentPicNumber", picNumber: picNumber}
        );
    };
}

chrome.browserAction.onClicked.addListener( function(){
    chrome.tabs.query({},function(tabs){
        for(i in tabs){
            chrome.tabs.executeScript(
                tabs[i].id,
                {file: 'createBanner.js'}, 
                messageCallback(tabs[i].id, iterator)
            );
        }
    });
});

Upvotes: 1

Sean Adams
Sean Adams

Reputation: 463

What does your manifest.json look like? Is createBanner.js listed in content_scripts? If so, you will be able to have it to execute on every page without needing to manually inject it with executeScript for each tab. e.g. (in manifest)

"content_scripts": [
{
  "matches": ["http://*/*", "https://*/*"],
  "js": ["createBanner.js"]
}
]

Upvotes: 0

Related Questions