vladamon
vladamon

Reputation: 307

Chrome extension tabs onUpdated event

I am building a chrome extension that should get notified every time a new tab has opened and load page, and for that purpose I'am using chrome.tabs.onUpdated event.

The problem is that in case an iframe is inserted on that page/tab that is hosted on some domain(has src), onUpdated event is trigered. Is there a way to differentiate these events for "real" tab load from those triggered for iframe load?

Upvotes: 6

Views: 7546

Answers (2)

ztrat4dkyle
ztrat4dkyle

Reputation: 2187

This question helped me with my extension, recognizing the difference between a new page and loading content on the same page, so thought I'd share my solution. First you need to call onUpdated in background.js:

Manifest

{
  "name": "My test extension",
  "version": "1",
  "manifest_version": 2,
  "background": {
    "scripts":["background.js"]
  },
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["contentscript.js"]
    }
  ],
  "permissions": [
    "tabs"
  ]
}

background.js

chrome.tabs.onUpdated.addListener(
  function(tabId, changeInfo, tab) {
    // read changeInfo data
    if (changeInfo.url) {
      // url has changed; do something here

    }
  }
);

Then you can expand that script to send message data from background.js to your content script (using chrome.runtime.sendMessage):

background.js (con't)

chrome.tabs.onUpdated.addListener(
  function(tabId, changeInfo, tab) {
    // read changeInfo data
    if (changeInfo.url) {
      // url has changed; do something here
      // like send message to content script
      chrome.tabs.sendMessage( tabId, {
        message: 'hello!',
        url: changeInfo.url
      })
    }
  }
);

And finally listen for that data in your extension's content script to be used however:

contentscript.js

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    // listen for messages sent from background.js
    if (request.message === 'hello!') {
      console.log(request.url) // new url is now in content scripts!
    }
});

You can pass whatever data you'd like from background.js. Hope that helps someone! \ (•◡•) /

Upvotes: 5

Xan
Xan

Reputation: 77551

tabs.onUpdated triggers when state changes between loading to complete. Presumably, inserting an iframe puts the tab to loading state again.

You could see if details.url is defined in onUpdated listener - if not, you know that the document's URL did not change.

Perhaps you should use webNavigation API instead for your purpose. There, you get a TransitionQualifier that you can use to filter out subframe navigation.

Upvotes: 3

Related Questions