As the title says, I want to wait until the html is parsed, and all stylesheets are loaded, because I need to use currentsyle
. However, I do not want to wait for images. So I cannot use load
event, as that waits for images. And I can't use the DOMContentLoaded
event, as that doesn't wait for stylesheets. I also cannot use document.body.appendChild
to add a script tag at the end of the document because this script is being run under the assumption that javascript on the page is disabled.
Is there seriously no event to wait on styles?
There are three possibly run-at
values for GM scripts - with corresponding document.readyState in brackets
document.readyState === 'loading'
)document.readyState === 'ineractive'
)document.readyState === 'complete'
)These are the only available injection points for your script
at start/end - no external resources will be loaded yet, so too early for what you want
at idle, all external resources are loaded, so too late for what you want
OK, you know all this, but I'm adding it for other future readers
if you load your script at document-end, you can add load
listeners to all <link rel="stylesheet"
like
Promise.all(Array.from(document.querySelectorAll('link[rel="stylesheet"]'), ss => new Promise(resolve => {
const href = ss.href;
const fulfill = status => resolve({href, status});
setTimeout(fulfill, 5000, 'timeout');
ss.addEventListener('load', () => resolve('load'));
ss.addEventListener('error', () => resolve('error')); // yes, resolve, because we just want to wait until all stylesheets are done with, errors shouldn't stop us
}))).then((results) => {
// results is an array of {href:'some url', status: 'load|error|timeout'}
// at this point stylesheets have finished loading
});