Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome extension, how to delay script until page is fully loaded

I am trying to get a DOM element by class name just after opening new website address in the tab. The problem is that I have no idea how to make it wait until the page is fully loaded. I tried alarms, setTimeOut, setTimeDelay and nothing works.

chrome.runtime.onMessage.addListener(message);

function message(msg) {
  chrome.tabs.update({url: 'https://www.website.com/'});
  chrome.tabs.executeScript({code:"var theBtn = document.getElementsByClassName('btn1');theBtn[0].click();"});
}

I am using chrome.runtime.sendMessage in the popup because I want to send web addresses from input, then I press a button and the code above is triggered. I simplified this because everything else works. The (msg) is just a website address

like image 481
M.Malinowski Avatar asked Oct 17 '22 01:10

M.Malinowski


1 Answers

Update:

That won't work, because executeScript won't have a tab to execute on, because you just killed (updated) that. You'll have to split it into Background and Content script:

  1. Background runs chrome.tabs.update
  2. Background sends exact target URL to Content
  3. Content listens on EVERY URL, but ignores all, unless it just got this exact URL from Background
  4. If so, Content runs the script, (or tells Background to run executeScript, but that seems silly), forgets the URL, and goes back to idling

Maybe the communication in 2-3 must go the other way: Content asks Background for EVERY page load if it should act on this URL.

Very interesting use case! I made a Proof of concept because it's X-mas!

Original:

Untested! Two options:

2. Add a load listener wrapper in the script:

chrome.tabs.executeScript({
  code:"window.addEventListener('load', function() { var theBtn = document.getElementsByClassName('btn1');theBtn[0].click(); });"
});

That's your code, wrapped inside window.addEventListener('load', function() { ... });. Adding the event listener is executed immediately, but the code inside only when the page is loaded.

1. Use executeScript's runAt option. I think you want document_end. See docs

Actually it looks like the default (document_idle) is more suited: "the browser chooses a time between "document_end" and immediately after window.onload" (from here)

like image 86
Rudie Avatar answered Oct 30 '22 04:10

Rudie