3

I'm learning Javascript and I'm very confused as to why I'm having issues with my javascript loading before the html when using Chrome. When I use Firefox and Edge, the page loads with the html first and then I get an alert. When I use Chrome though, I get the alert first and the background is just blank. Everything I'v learned so far seems to say that the js script should run after the html because it's at the bottom of the body tag.

Thanks!

home.html page

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>
</head>
<body>
<h1>Hi, testing chrome.</h1>
<h2>Is this working?</h2>
<ul>
<li>list1</li>
<li>list 2</li>
<li>list 3</li>
</ul>
<script type="text/javascript" src="myjs.js"></script>
</body>
</html>

myjs.js page

alert("Am I working right?");
Abhinav
  • 530
  • 8
  • 21
jmido8
  • 31
  • 1
  • 2
  • 2
    try adding your code in document ready method – mohit sharma Nov 05 '18 at 06:57
  • 2
    Possible duplicate of [window.onload vs document.onload](https://stackoverflow.com/questions/588040/window-onload-vs-document-onload) – Vahid Nov 05 '18 at 07:02
  • 2
    Note the html does load, you just blocked the render thread is all. By the looks of it Firefox and Edge decide to do a render cycle of the so far loaded DOM right before displaying the alert box, where as Chrome doesn't. It is just how each vendor decided to implement their particular code. You will still be able to get references to the loaded DOM elements like the `
      `
    – Patrick Evans Nov 05 '18 at 07:12

7 Answers7

2

Since the JavaScript is single threaded, so when you call alert() function, it blocks other execution because it is an UI blocking function.

Abhinav
  • 530
  • 8
  • 21
Ropali Munshi
  • 2,757
  • 4
  • 22
  • 45
2

If you want to make your html load first before js make sure to wrap it with

document.addEventListener("DOMContentLoaded", function(event) { 
  // your code here
});
Mukyuu
  • 6,436
  • 8
  • 40
  • 59
  • Hi, I tried this but it is still the same. document.addEventListener("DOMContentLoaded", function(event) { alert("Am I working right?"); }); – jmido8 Nov 05 '18 at 07:32
1

The web uses an event driven model to sequence actions. You are correct in assuming that if the script appears at the end of a document, it will be parsed later than if it appeared at the beginning. But the HTML spec does not specify explicitly that HTML has to be rendered before your script is executed. So parsing and rendering are different operations, and chrome may choose to execute the script as soon as it finishes parsing it.

So how can you sequence your actions correctly? The web in general and javascript in particular are event driven. Your code can listen to a variety of events and respond to them as you please. In this case, you want to execute your script after your document has loaded. Take a look at the DOMContentLoaded event.

Here's your code modified to run when the DOMContentLoaded event is fired.

document.addEventListener("DOMContentLoaded", function() {
  alert("Am I working right?");
});

I have simply enclosed your alert function call in my event handler function. An event handler function (or callback) must be registered on the element that emits the event, in our case, the document object. This is done by calling addEventListener() on that object with two arguments. The first is the event name that we want to listen to as a string, and the second is a function that must be executed when the event is fired.

There are many events defined for many different elements, and you can even define your own custom events and respond to them.

Ananth
  • 848
  • 11
  • 26
  • thanks for the reply, I tried this and for Chrome, it still loads the alert first and then the html after – jmido8 Nov 05 '18 at 07:43
  • I just tried it out and it works correctly. Chrome may have cached the file locally. Try Ctrl+Shift+r to reload the page without hitting the local cache. – Ananth Nov 05 '18 at 07:56
0

Something you should always do in your JS files is put every direct code and DOM-related functions in a function to wait for the page to load.

In plain JavaScript :

window.onload = function() {
    //Your JS here
};

Note that according to this post, you can use document.onload(function() {...});

With JQuery :

$(function() {
    //Your JS here
});
Jean-Marc Zimmer
  • 537
  • 6
  • 20
  • Note since their code is at the bottom of the page all the DOM elements above it are already loaded. No need to put it in a load event in this situation if all your goal is to wait for the elements to exist – Patrick Evans Nov 05 '18 at 07:16
  • True. But when using an external JS file, it's always good to check if the page is loaded. Generally, one should always check inputs. – Jean-Marc Zimmer Nov 05 '18 at 07:19
  • when I tried putting it into window.onload(function() { ...}); I got an error that said window.onload is not a function – jmido8 Nov 05 '18 at 07:38
  • wooops ! `window.onload = function() {...};` and not `window.onload(function() {...});` Fixing that. – Jean-Marc Zimmer Nov 05 '18 at 07:42
  • Thank you so much! I'm still not really sure why it works but it is something I will look up. Is this something I should always look to do as a 'good practice'? – jmido8 Nov 05 '18 at 07:56
  • I'm not an excellent developer, but I think this is a good practice. (It will sometimes prevent errors) – Jean-Marc Zimmer Nov 05 '18 at 07:58
0

Place the code in Jquery document ready method

Sandeep
  • 24
  • 5
0

In plain JavaScript, try this in myjs.js

$(window).on("load", function(){
    var ss = document.createElement("script");
    ss.src = "myjs.js";
    ss.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(ss);
});

ELSE

Try this if jQuery is loaded.

$(function() {
    alert("Am I wrong?");
});

You will need to add

<script src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js">

in the tag to include jQuery

This should make sure that the page is loaded. But please be informed that tag is also a part of the DOM

If the requirement is to execute the external JS after loading HTML, then you can try this.

$(function() {
    var ss = document.createElement("script");
    ss.src = "myjs.js";
    ss.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(ss);
});
  • Can you please explain how would this fix the OP's problem? The IIFE doesn't change anything what matters here. – Teemu Nov 05 '18 at 07:10
  • 1
    This will not make sure the page is loaded first, you are using an IIFE which as the name implies immediately executes you are not changing the timing of execution. You are probably confusing the look of an IIFE and jQuery's `$(function(){})` which is jQuery's shorthand for `$(document).ready(function(){})` – Patrick Evans Nov 05 '18 at 07:19
  • @Teemu - I've edited the code snippet. Second snippet: The anonymous function executes once the document is loaded, then it create a script element and append it as a child to head element. Do let me know if you need more explanation – Vimal Maheedharan Nov 05 '18 at 07:21
  • @PatrickEvans - I've edited the code, missed the jQuery argument in the self calling function. Yeah the point is to make sure that the document is loaded. There are different ways by the way. https://www.sitepoint.com/types-document-ready/ – Vimal Maheedharan Nov 05 '18 at 07:24
  • There's no jQuery used in the question, though. It's not even loaded to the page ... – Teemu Nov 05 '18 at 07:26
  • 1
    You are still just using an IIFE, all your code is doing is passing in jQuery as an argument, also never actually using it in anyway. It needs to be `jQuery(function(){})` or `$(function(){})` if you are looking to use jQuery's dom ready event. The code on the page that you got the `(function(){})(jQuery)` from is for when you possibly have multiple jQuery instances loaded it has nothing to do with actual dom readiness – Patrick Evans Nov 05 '18 at 07:26
  • @PatrickEvans - Thanks so much for sharing/correcting the code. Will make sure that I will be bit more careful while submitting answers. Thank you! Also - The second snippet I have shared, will it solve the problem? – Vimal Maheedharan Nov 05 '18 at 08:43
  • @Teemu - Thanks for pointing that jQuery is not loaded in the page. I tried modifying the answer. Please have a look – Vimal Maheedharan Nov 05 '18 at 08:50
0

The function DOMContentLoaded let the browser execute a javascript code after the HTML content has loaded

  document.addEventListener("DOMContentLoaded", function(event) { 
    /*it is verry easy now, you can write code here which will be executed when the 
     html content will end loading*/
  });
Ir Calif
  • 460
  • 6
  • 7