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

1

6

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>
Kirovabad answered 13/9, 2013 at 16:26 Comment(7)
I guarantee the dom ready event is firing before the window onload. Instead, the code that binds TO it is being executed after the window onload, and since it's already ready at that point, it gets executed immediately.Equiangular
First of all, in my example, the page contains a big picture which will take awhile to get the picture loaded completely . Second, It printed the sentence - "required moudels have been loaded" out in the console and stopped. After awhile "window.onload" and "document.ready2" was printed. And "document.ready2" ALWAYS printed after "window.onload". Obvious dom-ready-binding-function didn't execute immediately when it was been binded to dom-ready.Kirovabad
What browser are you testing in? some browsers don't actually have a dom ready event, in those browsers jQuery's dom ready handler may trigger differently. How that situation is handled has changed from version to version (of jQuery), i think the most recent fires correctly in IE9/10 but late in IE7/8Equiangular
I'm seeing the behavior here in chrome: jsfiddle.net/SPHj8Equiangular
Actually... my fiddle was setup incorrectly, it was including two versions of jQuery. Now i'm not seeing the behavior you're describing: jsfiddle.net/SPHj8/1 sometimes the onload does happen before ready2, however, every time that happens, it's because the require modules being loaded happened after the onload, meaning the domready handler wasnt bound until after (which is expected once the image is cached)Equiangular
I've tested it with Chrome 29.0.1547.66, Firefox 23.0.1, IE10, IE9. All of them have same issue. However, IE8 and IE7 are ok. "document.ready2" printed before "window.onload". And you know what? Not only jquery but also domReady plugin(requirejs.org/docs/api.html#pageload) has same issue!!Kirovabad
Also investigated here - #18691331Abercromby
N
4

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.

Namnama answered 28/11, 2013 at 7:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.