最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use the domReady requireJS plugin correctly - Stack Overflow

programmeradmin3浏览0评论

Here is my main.js before using domReady:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'app' ], function(app) {
  app.initialize();
});

And app.js:

define([ 'jQuery', 'Underscore', 'Backbone', 'router',
    'services/Initializers/MainFrameInitializer',
    'services/Initializers/FlowsViewsInitializer',
    'services/Initializers/EditModuleInitializer',
    'services/Sandboxes/ModulesNavigationSandbox',
    'services/Sandboxes/ApplicationStateSandbox', 'DataModel/Constants' ],
    function($, _, Backbone, Router, MainFrameInitializer,
        FlowsViewsInitializer, EditModuleInitializer, ModulesNavigationSandbox,
        ApplicationStateSandbox, Constants) {
      var initialize = function() {
        // Pass in our Router module and call it's initialize function
        MainFrameInitializer.initialize();
        FlowsViewsInitializer.initialize();
        EditModuleInitializer.initialize();
        ApplicationStateSandbox.startCheckStatus();
        ModulesNavigationSandbox.navigate(Constants.Modules.Home);
        // Router.initialize();
      };

      return {
        initialize : initialize
      };
    });

All works fine until I optimize the project. I have figured out, that the script starts to run before the DOM is ready, something that was not true before the optimization. Anyway, I wish to use the domReady plugin to make sure the DOM is loaded first.

But, apparently, I have no idea how to do it correctly. Here is the new version of main.js:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'domReady', 'app' ], function(domReady, app) {
  domReady(app.initialize);
});

Very neat and very wrong, because app is loaded in parallel with domReady before the DOM is ready.

How do I fix it?

Thanks.

EDIT

I think I have understood our problem. The constructor functions of the app dependencies should not run any DOM dependent code. They should just return functions, capturing the DOM dependent logic. That logic should be executed from app.initialize, which is guaranteed to be run when the DOM is ready.

Here is my main.js before using domReady:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'app' ], function(app) {
  app.initialize();
});

And app.js:

define([ 'jQuery', 'Underscore', 'Backbone', 'router',
    'services/Initializers/MainFrameInitializer',
    'services/Initializers/FlowsViewsInitializer',
    'services/Initializers/EditModuleInitializer',
    'services/Sandboxes/ModulesNavigationSandbox',
    'services/Sandboxes/ApplicationStateSandbox', 'DataModel/Constants' ],
    function($, _, Backbone, Router, MainFrameInitializer,
        FlowsViewsInitializer, EditModuleInitializer, ModulesNavigationSandbox,
        ApplicationStateSandbox, Constants) {
      var initialize = function() {
        // Pass in our Router module and call it's initialize function
        MainFrameInitializer.initialize();
        FlowsViewsInitializer.initialize();
        EditModuleInitializer.initialize();
        ApplicationStateSandbox.startCheckStatus();
        ModulesNavigationSandbox.navigate(Constants.Modules.Home);
        // Router.initialize();
      };

      return {
        initialize : initialize
      };
    });

All works fine until I optimize the project. I have figured out, that the script starts to run before the DOM is ready, something that was not true before the optimization. Anyway, I wish to use the domReady plugin to make sure the DOM is loaded first.

But, apparently, I have no idea how to do it correctly. Here is the new version of main.js:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'domReady', 'app' ], function(domReady, app) {
  domReady(app.initialize);
});

Very neat and very wrong, because app is loaded in parallel with domReady before the DOM is ready.

How do I fix it?

Thanks.

EDIT

I think I have understood our problem. The constructor functions of the app dependencies should not run any DOM dependent code. They should just return functions, capturing the DOM dependent logic. That logic should be executed from app.initialize, which is guaranteed to be run when the DOM is ready.

Share Improve this question edited Feb 21, 2012 at 7:19 mark asked Feb 20, 2012 at 13:13 markmark 62.8k95 gold badges339 silver badges667 bronze badges 4
  • Why is it wrong for domReady and app to be loaded in parallel? You only actually invoke code from app when the DOM is ready. Or have I misunderstood? – Paul Grime Commented Feb 20, 2012 at 15:07
  • It is possible that it is me who misunderstands how the stuff works. Loading app involves loading all of the app dependencies (and there are quite a few), then these dependencies are invoked and the results are passed to the app factory method, which returns the app itself. If I understand it correctly, the dependencies of app are executed in parallel with domReady, which means they may run before the DOM is fully loaded. – mark Commented Feb 20, 2012 at 15:13
  • Nothing runs unless your factory function that you pass to define() actually runs code. Usually, the factory function just creates an object with methods that can be called at some point in the future (you have done this). So even though a call to define() will run the factory function, you only do real app work when you want to. Like you have done by passing app.initialize to the domReady function. It seems fine to me. – Paul Grime Commented Feb 20, 2012 at 15:29
  • I have edited my post. Is that what you mean? – mark Commented Feb 21, 2012 at 7:20
Add a comment  | 

3 Answers 3

Reset to default 7

Perhaps I am missing something, but wouldn't you make your life a lot easier by doing:

require(['jQuery', 'app' ], function(jQuery, app) {
  jQuery(function ($) {
    app.initialize();
  });
});

in your main.js?

By requiring the app from inside the domReady callback function, you should be able to require the domReady module, and then the app module synchronously.

define(['require', 'domReady'], function(require, domReady) {
  domReady(function() {
    require(['app'], function(app) {
      app.initialize();
    });
  });
});

If you follow the doc at: http://requirejs.org/docs/jquery.html, you will be invited to embed a require-jquery library in the head of your document:

<script data-main="main" src="libs/require-jquery.js"></script>

However, if you look at the source for the example, made available on github, you will see that 'require-jquery.js' is generated by simple concatenation of the require lib file and the jquery lib file:

 cat require.js jquery.js > ../jquery-require-sample/webapp/scripts/require-jquery.js

That means that you could replace the script embed in the head part with the following script embeds anywhere in your document (for instance at the very bottom of it).

  <script src="libs/require.js"></script>
  <script src="libs/jquery-1.8.0.js"></script>
  <script>require(["main"]);</script>

Because the jquery lib defines itself as a module with:

  define( "jquery", [], function () { return jQuery; } );

You can thereafter use jquery as a require reference in any of your script. For instance:

  require(["jquery"], function($) { }
发布评论

评论列表(0)

  1. 暂无评论