How should the JS inside a be written? Does it really not use the DOM?

4 days ago 13
ARTICLE AD BOX

Some people say that JS loaded with async might be independent of the DOM.

Yes, but emphasis on the "might be" part, because async scripts can use the DOM, it just needs some initial entrypoint logic for safety, because line 1 of the script can run before any <body> HTML/DOM is available - or it might run at any point while the DOM loads, so because there is no guarantee about the browser's document's DOM state it means the script needs to be written defensively.

So JS inside an async <script> element can use the DOM, but the script must first check document.readyState first - and depending on the current readyState can either continue immediately - or it must schedule itself to run on/after DOMContentLoaded.

For example:

MyAsyncLoadedScript.js:

// (This is a plain ol' JS, with top-level code. No modules, no UMD, no AMD, no require(), no imports, etc). if( document.readyState === 'loading' ) { // Document is not ready yet (i.e. it is *not* yet safe to manipulate the DOM, excepting objects like `document` and `window`). // ...so we cannot safely run this script's main function yet. // ...so schedule it to run on DOMContentLoaded using addEventListener: document.addEventListener( 'DOMContentLoaded', theRestOfTheScriptProgram ); // However, if this script depends on all external resources (images, other scripts, etc) being fully loaded before it runs, then use the `window` 'load' event instead of 'DOMContentLoaded'. // See https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event // window.addEventListener( 'load', theRestOfTheScriptProgram ); } else if( document.readyState === 'complete' ) { // The document (the DOM and all resources) is fully loaded already, i.e. the 'load' event already fired. // ...so it's safe to immediately run the main function synchronously: theRestOfTheScriptProgram(); } else /* implicit: document.readyState === 'interactive' */ { // The 'interactive' state sits in-between 'loading' and 'complete', from 'DOMContentLoaded' until 'load'. // ...so if the script does not depend on all external resources (images, videos, etc) being already-loaded, then it's safe to synchronously run the main function here: theRestOfTheScriptProgram(); } function theRestOfTheScriptProgram() { // Inside this function, it's safe to manipulate the DOM. // For example, `document.querySelectorAll` will behave predictably. }
Read Entire Article