tonco tonco - 2 months ago 16
Javascript Question

window.load & $(document).ready() behaves differently with jQuery version 2 and 3

in this small project I tried to play with

window.load
and
$(document).ready()


https://jsfiddle.net/23rupa07/

What I read was that
$(document).ready()
is triggered immediately when DOM is loaded and
window.load
is waiting until for example images are loaded.

For jQuery version 2.2.4 it's working as is mentioned above, but when I change jQuery to version 3.1.0 the order is reverted.

Check screenshot. Does anyone know why?
enter image description here

Answer

document ready change between jQuery2 and jQuery3

One of the changes of jQuery 3 is that as of now - the document-ready handlers are asynchronous, even if the document is currently ready at the point where the handler is added. This provides a consistent code execution order that is independent of whether the document is ready or not[1].

This change required implementing a queue functionality for the document-ready callbacks, and this also affect other calls for events that are not called from the jQuery object.

If we take this code for example:

window.addEventListener('DOMContentLoaded', function() {
  console.log('vanilla - DOMContentLoaded');
});
$(function(){
  console.log('jquery - DOM loaded');
});

jQuery2 will give us:

jquery - DOM loaded
vanilla - DOMContentLoaded

jQuery3 will give us:

vanilla - DOMContentLoaded
jquery - DOM loaded

The behavior we see in the OP is related to a race-condition between the "fire" event of the document-ready's callbacks and the window.onload function.

This code will can show that the two functions run "at the same time", and it's only a matter of code-execution inside the VM of the browser:

$(function(){
    console.log('jquery - DOM loaded')
});

window.onload = function(){
    setTimeout(function() {
        console.log('window - loaded');
    }, 0);
}
<script type="text/javascript" src="//code.jquery.com/jquery-3.1.0.js"></script>

Regarding the question about the images - since the images are already in your cache when you load the document, it only seems like the window.onload function is called before the document.ready (it's a race condition), however if you will make sure the images will never cache - you will see that you get exactly the same results for both jquery2 and jquery3.

jQuery 2

$(document).ready(function(){
  console.log('jquery - DOM loaded');
});

window.onload = function(){
  console.log('window - loaded');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
  for (i = 0; i < 6; i++) {
    
    document.writeln('<img src="https://o.aolcdn.com/commerce/autodata/images/USC60LGC051A021001.jpg?'+ parseInt(Math.random()*10000) +'" alt="">');
  }
</script>

jQuery 3

$(document).ready(function(){
  console.log('jquery - DOM loaded');
});

window.onload = function(){
  console.log('window - loaded');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
  for (i = 0; i < 6; i++) {
    
    document.writeln('<img src="https://o.aolcdn.com/commerce/autodata/images/USC60LGC051A021001.jpg?'+ parseInt(Math.random()*10000) +'" alt="">');
  }
</script>