DOMContentLoaded
AKA jQuery.ready()
is fired when the browser is done parsing the DOM, which includes script elements and iframes.
The load event is fired after
DOMContentLoaded
is fired. At this point, all resources are downloaded and ready which includes frames, images, etc. The browser's stop button stops spinning at this point.index.html
<html> <head> <script type="text/javascript"> console.log("HEAD_SCRIPT_INIT"); </script> </head> <body> <script type="text/javascript"> console.log("SCRIPT_TAG_1_INIT"); </script> <script type="text/javascript"> console.log("SCRIPT_TAG_2_INIT"); document.addEventListener("DOMContentLoaded", function(){ for(var i=0; i<10; i++) console.log("SCRIPT_TAG_2_DOM_READY", i); }); addEventListener("load", function(){ console.log("SCRIPT2WINDOWLAOD"); }) </script> <iframe srcdoc=' <script type="text/javascript"> for(var i=0; i<10; i++) console.log("IFRAME_1_INIT:", i); </script>'> </iframe> <iframe srcdoc=' <script type="text/javascript"> for(var i=0; i<10; i++) console.log("IFRAME_2_INIT:", i); </script>'> </iframe> <iframe src="iframe_3.html"></iframe> <iframe srcdoc=' <script type="text/javascript"> console.log("IFRAME_4_INIT"); document.addEventListener("DOMContentLoaded", function(){ console.log("IFRAME_4_DOM_READY"); }) window.onload = function(){ console.log("IFRAME_4_WINDOW_ONLOAD"); } </script>'> </iframe> <script async type="text/javascript" src="script_3.js"></script> <script type="text/javascript" src="script_4.js"></script> <script type="text/javascript"> console.log("SCRIPT_TAG_5_INIT"); </script> <script type="text/javascript"> var script = document.createElement('script'); script.innerText = 'console.log("HEAD_APPENDCHILD_INIT")'; document.getElementsByTagName('head')[0].appendChild(script); </script> <script type="text/javascript"> addEventListener("load", function(){ console.log("SCRIPT7"); }) </script> </body> </html>
iframe_3.html
<script type="text/javascript"> console.log("IFRAME_3_INIT"); document.addEventListener("DOMContentLoaded", function(){ console.log("IFRAME_3_DOM_READY"); }) window.onload = function(){ console.log("IFRAME_3_WINDOW_ONLOAD"); } </script>
script_3.js
console.log("SCRIPT_TAG_3_INIT");
script_4.js
console.log("SCRIPT_TAG_4_INIT");
Now, open
index.html
in a browser. Now open console
and draw the following conclusions for yourself from our experiment.
As the downloaded html is parsed by the browser from top to bottom, any
script
tags in the head
are executed followed by any script
tags or iframe
tags in the body
.
Whether a script is specified inline or with an 'src' attribute, execution is done in order and it blocks parsing of the DOM unless the 'async' attribute is specified. 'async' scripts are downloaded out of order with respect to the other resources in the DOM. Downloading them will not block parsing the rest of the DOM, but they will block the load event during execution (it doesn't block
DOMContentLoaded
as far as I know).
Any
script
tags within iframe
tags are parsed and executed right there if the content of the iframe
is specified inline. If the iframe
has an 'src' attribute, parsing of the DOM isn't blocked and the resource is downloaded in the background and executed when it's ready. Else it blocks further parsing. Also they fire their own DOMContentLoaded
and load events and thus block the parents DOMContentLoaded
and load events.
Iframes do not execute in parallel.
No script is EVER interrupted and execution is not switched to a different script just because an event was fired. The firing of every event blocks until the current block is done executing.
A script appended to
head
via JS code will be executed immediately (just like inline JS).
No comments:
Post a Comment