【问题标题】:How to use the domReady requireJS plugin correctly如何正确使用 domReady requireJS 插件
【发布时间】:2013-05-11 07:22:48
【问题描述】:

这是我在使用 domReady 之前的 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([ 'app' ], function(app) {
  app.initialize();
});

还有 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
      };
    });

在我optimize 项目之前一切正常。我发现,脚本在 DOM 准备好之前就开始运行了,这在优化之前是不正确的。无论如何,我希望使用domReady 插件来确保首先加载DOM。

但是,显然,我不知道如何正确地做到这一点。这是 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);
});

非常整洁也非常错误,因为appdomReady 是在DOM 准备好之前并行加载的。

我该如何解决?

谢谢。

编辑

我想我已经理解了我们的问题。 app 依赖项的构造函数不应运行任何 DOM 依赖代码。它们应该只返回函数,捕获依赖于 DOM 的逻辑。该逻辑应该从app.initialize 执行,保证在DOM 准备好时运行。

【问题讨论】:

  • 为什么domReadyapp并行加载会出错?只有当 DOM 准备好时,您才真正从 app 调用代码。还是我误会了?
  • 可能是我误解了这些东西的工作原理。加载app 涉及加载所有应用程序依赖项(并且有很多),然后调用这些依赖项并将结果传递给应用程序工厂方法,该方法返回app 本身。如果我理解正确的话,app 的依赖与domReady 并行执行,这意味着它们可能在 DOM 完全加载之前运行。
  • 没有任何东西运行,除非你传递给define() 的工厂函数实际运行代码。通常,工厂函数只是创建一个对象,其方法可以在在将来的某个时间点调用(你已经这样做了)。因此,即使调用define() 将运行工厂函数,您也只能在需要时执行真正的 应用程序工作。就像您通过将 app.initialize 传递给 domReady 函数所做的那样。我觉得很好。
  • 我已经编辑了我的帖子。是这个意思吗?

标签: javascript requirejs domready


【解决方案1】:

也许我遗漏了一些东西,但你不会让你的生活更轻松吗:

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

在你的main.js?

【讨论】:

  • 我们正在使用 jQuery,但你不能直接使用它,因为 jQuery 没有将自己定义为 requireJS 意义上的模块。它首先需要一些准备工作,我们会这样做。另外,请注意app 确实依赖于jQuery,这是它的第一个依赖项。
  • jQuery is 自 iirc 1.7 起兼容 AMD。如果您依赖某个以前的版本,您始终可以使用加载程序。您的应用程序和主程序都依赖于 jQuery,不会违反任何内容(jquery 仍然加载一次),但它允许您不添加另一个插件。
  • 好的,但是这个方案仍然要求app所依赖的模块的工厂方法不操作DOM,因为app依赖关系在加载jQuery的同时被解析和调用。原来的问题依然存在。但似乎我已经弄清楚这里有什么问题 - 请参阅我的帖子的编辑。
  • 没有什么要求你不使用 jQuery/操纵你的 dom。这只是简单的js。如果您想使用它的 ready(),可以将 jQuery 作为依赖项添加到您的 main 中。
  • 从 jQuery 1.7 开始,jQuery 将自己定义为一个模块,上面的代码将是有效的。在 1.7 之前,您可以使用 require-jquery.js 从 require js 加载 jQuery 并将其定义为模块。
【解决方案2】:

通过在 domReady 回调函数中请求应用,您应该能够同步请求 domReady 模块,然后同步请求应用模块。

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

【讨论】:

    【解决方案3】:

    如果您关注http://requirejs.org/docs/jquery.html 上的文档,您将被邀请在文档头部嵌入一个 require-jquery 库:

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

    但是,如果您查看示例的源代码(在 github 上提供),您会看到“require-jquery.js”是由 require lib 文件和 jquery lib 文件的简单连接生成的:

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

    这意味着您可以在文档的任何位置(例如在文档的最底部)将嵌入在头部的脚本替换为以下嵌入的脚本。

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

    因为 jquery 库将自己定义为一个模块:

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

    此后,您可以在任何脚本中使用 jquery 作为 require 引用。例如:

      require(["jquery"], function($) { }
    

    【讨论】:

      猜你喜欢
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 2017-01-17
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      相关资源
      最近更新 更多