Reputation:
I am building a Chrome extension and in my contentScript, I have a function which loops all the <link>
elements and check whether it has rel="preconnect"
attribute. If true, the icon of the extension will change.
The contentScript runs at document start and the function. The function runs onDomLoaded
. When the prerender is directly in HTML code, the extension works perfectly. However when prerender is generated by JS, the icon wont change. Probably because the script is not fully loaded when onDomLoaded happens.
However when I use window.onload instead, it is really slow and the icon changes with a delay because it wait for the scripts to be fully loaded. How to deal with that situation and wait only if needed?
Manifest
content_scripts":
[{
"matches": ["https://*/*"],
"run_at": "document_start",
"js": ["js/contentScript.js"]
}]
ContentScript
document.addEventListener("DOMContentLoaded", function(event) {
//here I loop the page and if preconnect found, change the icon
)};
Upvotes: 1
Views: 708
Reputation: 73526
The proper tool for this task is MutationObserver that monitors DOM modifications.
Since MutationObserver at document_start can slow down the page (even if just by a little), we'll only observe the <head>
element, which is super-fast due to the small amount of elements there.
// there's no HEAD yet at document-start, let's wait until we have it
new MutationObserver((mutations, observer) => {
if (document.head) {
observer.disconnect();
monitorLinks();
}
}).observe(document.documentElement, {childList: true});
function monitorLinks() {
const onMutation = mutations => {
for (const {addedNodes} of mutations) {
for (const n of addedNodes) {
if (n.nodeName === 'LINK' && n.rel === 'preconnect') {
processLink(n);
}
}
}
};
// the HEAD may have some children already
onMutation([{
addedNodes: document.getElementsByTagName('link'),
}]);
// watch for the newly added children of HEAD
new MutationObserver(onMutation).observe(document.head, {childList: true});
}
function processLink(link) {
console.log(link);
}
Upvotes: 1