Search code examples
javascriptgoogle-chrome-extensionchrome-extension-manifest-v3

CHROME-EXTENSIONS: How can I run a function for different tabs at the same time?


I am working on a project that creates a google chrome extension. I have a function. I want that if new tab is onUpdated or onActivated this function works. Also, I want it works every tab simultaneously. How can I do that? Here is my code:

chrome.tabs.onActivated.addListener((activeInfo) => {
  chrome.tabs.query({ active: true }, (tabs) => {
    Process()
  })
})

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  chrome.tabs.query({ currentWindow: true }, (tabs) => {
    Process()
  })
})

Solution

  • This example will show how to apply same function on tab events onActivated and onActivated and to apply the function to all tabs on these events. You will want to do this in background service worker.

    Create an extension manifest specifying the service worker:

    {
      "name": "Example",
      "version": "1.0",
      "manifest_version": 3,
      "background": {
        "service_worker": "background.js"
      }
    }
    

    Next, in background.js script (the service worker), you will want to handle these events. The most basic implementation could look like this, and will call Process function on every tab, each time any tab is activated or updated:

    function Process(tab) {
        // now do something with each tab
        console.log(`Process tab id ${tab.id}`);
    }
    
    function ProcessAllTabs() {
        // do not specify query options to get 
        // all tabs in all windows for current user
        chrome.tabs.query({},
            (tabs) => tabs.map(Process));
    }
    
    // register the event listeners
    chrome.tabs.onActivated.addListener(ProcessAllTabs);
    chrome.tabs.onUpdated.addListener(ProcessAllTabs);
    

    If you debug this behavior, you will notice the tab update will call the even handler twice as the tab undergoes different update statuses. You may want to be more specific, and perhaps only call Process after tab has finished updating, or have more information about which event caused Process to be called. In that case, a more detailed implementation could look like this:

    // name the events
    const EventsEnum = {UPDATE: 'update', ACTIVATE: 'activate'};
    
    function Process(tab, eventName) {
        // now do something with each tab:
        console.log(`Process tab id ${tab.id} on ${eventName}`);
    }
    
    function ProcessAllTabs(eventName) {
        // do not specify query options to get
        // all tabs in all windows for current user
        chrome.tabs.query({},
            // pass more arguments to Process function
            (tabs) => tabs.map(tab => Process(tab, eventName)));
    }
    
    // register the event listeners
    chrome.tabs.onActivated.addListener(
        // include event name
        () => ProcessAllTabs(EventsEnum.ACTIVATE));
    
    chrome.tabs.onUpdated.addListener((tab, changeInfo) => {
        // require that tab update is complete before proceeding
        if (changeInfo.status === "complete") {
            ProcessAllTabs(EventsEnum.UPDATE)
        }
    });