Why DOM ready event always runs after window.onload event with requirejs?

3.5k views Asked by At

I am using jquery and requirejs with my projects. Recently, I've found something that I never expected. What it is If I load jquery via requirejs. The DOM ready event always fire after window.onload event .

Here is my example: http://jsbin.com/ozusIBE/2

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>

  <img src="http://thejetlife.com/wp-content/uploads/2013/06/Times_Square_New_York_City_HDR.jpg" />

  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.5/require.min.js"></script>
  <script>

    window.onload = function () {
        console.log('window.onload');
    };
    $(function () {
            console.log('document.ready1');
    });

    requirejs.config({
        paths: { 
          jquery: ['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min']
        }
    });

    require(['jquery'], function () {
        console.log('required moudels have been loaded');

        $(function () {
            console.log('document.ready2');
        });
    });

  </script>
</body>
</html>

When I load the page without cache. The result in console is:

document.ready1
required moudels have been loaded
window.onload
document.ready2

Notice that ready2 always runs after window.onload. If I change the code a little bit then it makes difference.

//do not use requirejs to load jquery
//require(['jquery'], function () {
require([], function () { 
    console.log('required moudels have been loaded');
    $(function () {
        console.log('document.ready2');
    });
});

The result is:

document.ready1
required moudels have been loaded
document.ready2
window.onload

It seems that if I use requrejs to load jquery as an AMD module asynchronously. The DOM ready event is useless. Because DOM ready event will fires after window.onload.

I have no idea why this happened and is there any way I can fix this issue?



UPDATE:
Thank to dherman. As dherman mentioned about document.readyState. I've made small investigation and found a solution for the issue. I've tested it on Chrome and Firefox. It works well. However, It maybe not a perfect solution as all versions of IE can have interactive state before the DOM is fully loaded. (ref)

Here is my updated example: http://jsbin.com/ozusIBE/16

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>

  <img src="http://upload.wikimedia.org/wikipedia/commons/a/ab/NYC_-_Time_Square_-_From_upperstairs.jpg" />

  <script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.min.js"></script>
  <script>

    requirejs.config({
        paths: { 
          jquery: ['//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min']
        }
    });

    require(['jquery'], function () {
      console.log('required moudels have been loaded');

      var init = function(){
        console.log('document.ready');
      };

      if ( document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading' ){
        init();
      }else{
        $(function(){ init(); });
      }

    });


    window.onload = function () {
        console.log('window.onload');
    };


  </script>
</body>
</html>
1

There are 1 answers

0
dherman On BEST ANSWER

The native DOMContentLoaded event is firing exactly when it should be - when the document is ready. Since you're loading jQuery via RequireJS, you are potentially missing that event. When that occurs, jQuery does not know that the document is ready and must wait for the load event to be fired, or that document.readyState === "complete" in the case that load has already fired as well.