Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do modules prevent the need to use the DOMContentLoaded listener?

document.addEventListener('DOMContentLoaded', () => { 

});

I read that this event listener made sure, for regular scripts, that the JS wasn't going to reference nodes that hadn't been loaded yet. The content executes after DOMContentLoaded has been fired).

I've also read that a module is executed before DOMContentLoaded is fired (due to the defer attribute it has built in).

The modules I've used seem to not need the DOMContentLoaded listener. Can I confirm the DOMContentLoaded listener isn't needed by them to access nodes correctly?

Also, I can't think of how to test this so I'm asking here. If you know how I could, please do share!

like image 729
tonitone120 Avatar asked Aug 14 '20 22:08

tonitone120


People also ask

When should I use DOMContentLoaded?

The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. A different event, load , should be used only to detect a fully-loaded page.

On what event target should we listen for the DOMContentLoaded event?

The original target for this event is the Document that has loaded. You can listen for this event on the Window interface to handle it in the capture or bubbling phases.

What is the difference between DOMContentLoaded and load?

The load event is fired when the whole page has loaded, including all dependent resources such as stylesheets and images. This is in contrast to DOMContentLoaded , which is fired as soon as the page DOM has been loaded, without waiting for resources to finish loading.

Does DOMContentLoaded wait for scripts?

DOMContentLoaded and styles Naturally, it has to wait for styles to load. As DOMContentLoaded waits for scripts, it now waits for styles before them as well.


2 Answers

I think this article should clear things for you, it has great pictures https://flaviocopes.com/javascript-async-defer/#the-position-matters

When defer is present, it specifies that the script is executed when the page has finished parsing, therefore you can guarantee that the script gets access to the nodes without DOMContentLoaded

like image 50
dulebov.artem Avatar answered Oct 16 '22 20:10

dulebov.artem


When using defer, the scripts will indeed execute after the page has been fully downloaded in the order that they appeared.

You can see here a schema representing the behavior.

enter image description here

  • <script>

enter image description here

  • <script defer>

enter image description here

In any case, scripts are always executed before DOMContentLoaded, you can test that theory here :

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

<script type="text/javascript">
  document.addEventListener('DOMContentLoaded', () => {
    alert("Alert from script")
  });
  $(document).ready(function() {
    alert("Alert from jQuery")
  });
</script>

<!-- Alerts "Alert from defer -->
<script defer="defer" type="text/javascript" src="https://pastebin.com/raw.php?i=5tF5s4mB"></script>

And unless you remove the alert from the ready state, all scripts will execute before them, otherwise they get executed in the order they appear in the DOM.

So you can be sure that all code inside DOMContentLoaded will be able to access the fully loaded DOM.

On an end note, do watch out of defer's compatibility across all browsers.

Script attributes async and defer, don’t block DOMContentLoaded. JavaScript modules behave like defer, they don’t block it too.

This can be tested using type="module"

<script type="module">
  alert("Alert from script")
</script>

<script type="text/javascript">
  alert("Page loaded")
</script>

As you can see, the page loads before executing any modules, no matter the order.

like image 34
Alexandre Elshobokshy Avatar answered Oct 16 '22 20:10

Alexandre Elshobokshy