为什么DOM ready事件总是在带有requirejs的window.onload事件之后运行?

时间:2013-09-13 16:26:56

标签: jquery requirejs onload domready

我在项目中使用jquery和requirejs。最近,我发现了一些我从未想过的东西。它是什么如果我通过requirejs加载jquery。 DOM ready事件总是在window.onload事件之后触发。

以下是我的示例: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>

当我加载没有缓存的页面时。控制台中的结果是:

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

请注意,ready2始终在window.onload之后运行。 如果我稍微更改一下代码,那就会有所不同。

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

结果是:

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

似乎我使用requrejs异步加载jquery作为AMD模块。 DOM ready事件没用。因为DOM就绪事件将在window.onload之后触发。

我不知道为什么会这样,有什么办法可以解决这个问题吗?



更新:
感谢dherman。 正如dherman提到 document.readyState 。我做了一些小调查,找到了解决这个问题的方法。我在Chrome和Firefox上测试过它。它运作良好。但是,它可能不是一个完美的解决方案,因为所有版本的IE都可以在DOM完全加载之前具有交互状态。 (ref

以下是我更新的示例: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 个答案:

答案 0 :(得分:4)

当文档准备就绪时,本机DOMContentLoaded事件正好在它应该发生时触发。由于您是通过RequireJS加载jQuery,因此您可能错过了该事件。发生这种情况时,jQuery不知道文档已准备就绪,必须等待load事件被触发,或者document.readyState === "complete"在已经解雇的情况下也是如此。