4
votes

Having the code below:

<html>
    <head>  

        <script>            
            function elem_onload() {
                console.log("elem_onload");
            };      
        </script>

    </head>

    <body onload="elem_onload()">       
        <script type="text/javascript" src="script.js" defer></script>      
    </body>
</html>

script.js:

console.log("external script");

the defer attribute doesn't seems to work. The output is:

external script
elem_onload

whether with or without defer attribute. Shoudn't it be

elem_onload
external script 

with defer defined?

Duplicated answer!?

I'd like to state that my answer isn't duplicate of

How exactly does <script defer=“defer”> work?

The referenced recommended answer is about inline script where the browser behavior is clear for me - it simply ignores defer. My question is about external script in which case the browser should execute the external deferred script

after the document has been parsed

as documentation states hence after onload event.

So I'm waiting for an appropriate answer...

2
4.21.1 Script element: "There are three possible modes that can be selected using these attributes. If the async attribute is present, then the script will be executed as soon as it is available, but without blocking further parsing of the page. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page"Andreas
So You suggest that "onload" event is always triggered when the page has been parsed and therefore after deferred script?Mulligan81
Try setting type and src of <script type=""></script> at close of elem_onloadguest271314
12.2.6 The end: Step 3. Execute all deferred scripts; Step 4. Fire DOMContentLoaded; ... Step 7: Fire load eventAndreas

2 Answers

7
votes

The external script deferred by the defer attribute is executed before the (DOMContentLoaded) is fired, i.e. when the initial HTML document has been completely loaded and parsed. The onLoad attribute on a <body> tag, on the other hand, fires only when a web page is fully loaded.

Therefore, the defer attribute is indeed working. You may test it by trying the two cases below. In both cases the content of script.js file should be this:

console.log(document.getElementById('sample').innerHTML);

CASE 1 HTML - with defer --> logs "Sample text"

<body onLoad="elem_onload()">       
<script type="text/javascript" src="script.js" defer></script>    
<div id="sample">Sample text</div>
</body>

CASE 2 HTML - without defer --> logs an error

<body onLoad="elem_onload()">       
<script type="text/javascript" src="script.js"></script>    
<div id="sample">Sample text</div>
</body>
-2
votes

Thx. all for help.

So the statement "...after the document has been parsed" from original doc. (MDN <script> tag) refers say step #0 from 12.2.6 The end

when document is completely parsed and now there are several tasks to be done on that occasion. Those tasks includes running external deferred scripts which is prior (#3) to onload event.

Am I right?