Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chrome.webNavigation.onCompleted - Event firing multiple times

I load plagin for Inject code to page, the manifest code:

{
  "name": "any",
  "version": "1.0",
  "permissions": [
    "webNavigation",
    "*://*/*" 
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "manifest_version": 2
}

And the background.js:

chrome.webNavigation.onCompleted.addListener(function(details) {
    chrome.tabs.executeScript(details.tabId, {
        code: 'console.log("A")'
    });
});

The problem is the event firing a few times after page load, I want the event just one time. What is my mistake? I would appreciate any help on.

like image 404
ABE Avatar asked Jun 12 '16 21:06

ABE


People also ask

Why am I receiving events from multiple processes in chrome?

Due to the multi-process nature of Chrome, a tab might use different processes to render the source and destination of a web page. Therefore, if a navigation takes place in a new process, you might receive events both from the new and the old page until the new navigation is committed (i.e. the onCommitted event is send for the new main frame).

What are the events fired after a navigation is successfully completed?

For a navigation that is successfully completed, events are fired in the following order: Any error that occurs during the process results in an onErrorOccurred event. For a specific navigation, there are no further events fired after onErrorOccurred.

Can I have multiple webnavigation events with the same frameid?

Therefore, if a navigation takes place in a new process, you might receive events both from the new and the old page until the new navigation is committed (i.e. the onCommitted event is send for the new main frame). In other words, it is possible to have more than one pending sequence of webNavigation events with the same frameId.

Why does webnavigation have a different time stamp than chrome?

It's important to note that some technical oddities in the OS's handling of distinct Chrome processes can cause the clock to be skewed between the browser itself and extension processes. That means that WebNavigation's events' timeStamp property is only guaranteed to be internally consistent.


2 Answers

chrome.webNavigation.onCompleted is invoked even when the navigation occurs in a subframe. One way to capture it only once is to implement your code with a condition for frame id. frame id = 0 corresponds to the parent frame. Your code would look like :

chrome.webNavigation.onCompleted.addListener(function(tab) {
    if(tab.frameId==0){
    //logic
    }
});

detailed documentation available here : https://developers.chrome.com/extensions/webNavigation

like image 118
Ayush Avatar answered Sep 19 '22 00:09

Ayush


The best practice is to use named functions, register them when ready and, on the performance point of view, only for the requested URLs (if possible). in the next example the listener is getting removed before registered plus only if the filter contains URLs:

if (filter.url.length < 1) {
    resolve(dictionary);
    return;
}

if (chrome.webNavigation.onBeforeNavigate.hasListener(onBeforeNavigate))
    chrome.webNavigation.onBeforeNavigate.removeListener(onBeforeNavigate);
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate, filter);

and the named should follow this pattern:

const onBeforeNavigate = (details) => {
    if (details.frameId > 0)
        return;
...
}

see more info here: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation/onCompleted

like image 29
EladTal Avatar answered Sep 20 '22 00:09

EladTal