Sam Chen
Sam Chen

Reputation: 2148

Content script programatically injected by Chrome extension background page got injected multiple times

I have a chrome extension, say it injects content script a.js into urls matching 'http://example.com/*'. Then when I click some page elements in example.com page, a.js would ask background to create a new tab with defined url, and programatically inject a content script b.js into the new tab, you can check the code down:


chrome.tabs.create({
    url: 'http://example.com'
}, function (tab) {
    var taskTab = tab.id;
    chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
        if (tabId === taskTab) {
            chrome.tabs.executeScript(taskTab, {
                file: 'scripts/b.js'
            });
        }
    });
});

The problem is, the content script b.js would get injected into the new tab for a lot times. I also tried the chrome.webNavigation, the result is the same.

So if I want the b.js got injected into the new tab for only one time? how can i make it?

By the way, the b.js is actually a remote file, I load it into page by jQuery, here to simplify the question I make it a local file.

Thanks very much.

update

I had figure out what's going on with my code.

First, it's wrong for me to wrap the onUpdated event listener inside the create callback, every time I create a new tab, close it, create it again, the event listener would got bind one more time. The more, the more.

Second, @Xan was right, I could do it by checking changeInfo.status. So the code would be:


var taskTab;
chrome.tabs.create({
    url: 'http://example.com'
}, function (tab) {
    taskTab = tab.id;
});
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
  if (changeInfo.status === 'complete'){
    if (tabId === taskTab) {
       chrome.tabs.executeScript(taskTab, {
            file: 'scripts/b.js'
        });
    }
  }
});

And that b.js would only be injected for once, no matter it's a local file or a remote file loaded by jQuery.

Upvotes: 1

Views: 1724

Answers (1)

Xan
Xan

Reputation: 77523

  1. onUpdated event can fire for a lot of reasons:

    object changeInfo:

    Lists the changes to the state of the tab that was updated.

    string (optional) status: The status of the tab. Can be either loading or complete.

    string (optional) url: The tab's URL if it has changed.

    boolean (optional) pinned: The tab's new pinned state.

    string (optional) favIconUrl: The tab's new favicon URL.

    You might want to filter onUpdated events by those properties of changeInfo

  2. Failsafe method: when you inject a second script, set some guard variable that is checked for undefined before you execute the rest of the script. Any other attempts to inject the script will be in the same context and will see the variable set. Kind of like C's #ifndef includes.

Upvotes: 1

Related Questions