And Finally And Finally - 1 year ago 110
Javascript Question

JavaScript in external file is executed before the script tag's onload event

I've read that

defer
won't necessarily delay the loading of an external script, but it will defer the execution of the script till after the HTML has been parsed.

enter image description here

As an experiment I add a line to the bottom of a file containing jQuery which emits an event when execution gets to the end of the JavaScript:

window.dispatchEvent(new Event('jQuery-executed'));


I include the jQuery file in my test page with a
defer
attribute:

<script src="jquery-3.2.1.js" defer onload="console.log('jQuery loaded', Date.now());"></script>
<script>
window.addEventListener('DOMContentLoaded', function(){
console.log('DOMREADY', Date.now());
});

window.addEventListener('jQuery-executed', function(){
console.log('jQuery executed', Date.now());
});
</script>


I have an
onload
handler on the script tag to tell me when the file was loaded, and other functions output console logs on DOMContentLoaded and when the jQuery is executed.

Why when I view this page do I get this?

enter image description here

Surely things should happen in a different order? Shouldn't jQuery only be executed after the file containing it has loaded? And why's it being executed before DOMContentLoaded?

Answer Source

The HTML5 spec is weird and hard to read, but it does say that deferred script content should be evaluated before the "load" event is fired. If you think about it, that's really a good thing: if you have some code that's waiting for a script to load, it's probably because you want to use some code that the script provided. If the "load" event fired before the script ran, it would not really be useful to have a "load" handler.

Same goes for "DOMContentReady": code waiting for that event to fire properly expects that all the script content imported by the page is ready to be exploited.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download