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.
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).
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.
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With