Javascript 如何正确使用domReady requireJS插件
在使用domReady之前,这里是我的main.js:Javascript 如何正确使用domReady requireJS插件,javascript,requirejs,domready,Javascript,Requirejs,Domready,在使用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',
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
};
});
在我完成项目之前,一切都很好。我发现,在DOM准备就绪之前脚本就开始运行了,这在优化之前是不正确的。无论如何,我希望使用插件来确保首先加载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);
});
非常整洁而且非常错误,因为在DOM就绪之前,app
与domReady
并行加载
我怎么修理它
谢谢
编辑
我想我已经理解我们的问题了。
app
依赖项的构造函数不应运行任何依赖于DOM的代码。它们应该只返回函数,捕获依赖于DOM的逻辑。应该从app.initialize
执行该逻辑,该逻辑保证在DOM准备就绪时运行。也许我遗漏了一些东西,但您是否可以通过执行以下操作来简化您的生活:
require(['jQuery', 'app' ], function(jQuery, app) {
jQuery(function ($) {
app.initialize();
});
});
在您的main.js
?中,如果您遵循以下文档:,您将被邀请在文档头部嵌入require jquery库:
<script data-main="main" src="libs/require-jquery.js"></script>
这意味着您可以将嵌入头部的脚本替换为嵌入文档中任何位置(例如,在文档的最底部)的以下脚本
此后,您可以在任何脚本中使用jquery作为require引用。例如:
require(["jquery"], function($) { }
通过从domReady回调函数内部请求应用程序,您应该能够同步地请求domReady模块,然后请求应用程序模块
define(['require', 'domReady'], function(require, domReady) {
domReady(function() {
require(['app'], function(app) {
app.initialize();
});
});
});
为什么并行加载
domReady
和app
是错误的?只有当DOM准备就绪时,才能从app
调用代码。还是我误解了?可能是我误解了这些东西的工作原理。加载app
涉及加载所有的app依赖项(其中有很多),然后调用这些依赖项并将结果传递给app factory方法,该方法返回app
本身。如果我理解正确,app
的依赖项与domReady
并行执行,这意味着它们可能会在DOM完全加载之前运行。除非传递给define()
的工厂函数实际运行代码,否则不会运行任何操作。通常,factory函数只是创建一个对象,其中包含可以在将来某个时候调用的方法(您已经这样做了)。因此,即使对define()
的调用将运行工厂函数,您也只能在需要时执行真正的应用程序工作。就像您通过将app.initialize
传递到domReady
函数所做的那样。我觉得不错。我已经编辑了我的帖子。这就是你的意思吗?我们正在使用jQuery,但你不能直接这样使用它,因为jQuery并没有将自己定义为requireJS意义上的模块。这首先需要一定的准备,我们会做的。另外,请注意,app
确实依赖于jQuery
,这是它的第一个依赖项。自iirc 1.7以来,jQuery与AMD兼容。如果依赖于某个以前的版本,则始终可以使用加载程序。依赖于jQuery的应用程序和main不会违反任何规定(jQuery仍然加载一次),但它将允许您不添加其他插件。好的,但此方案仍然要求app
所依赖的模块的工厂方法不操作DOM,因为app
依赖项是在jQuery加载的同时解析和调用的。原来的问题仍然存在。但我似乎已经弄明白了这里的症结所在——请看我文章的编辑。没有任何东西要求您不使用jQuery/操纵dom。它只是简单的js。如果您想使用其ready(),可以将jQuery作为依赖项添加到main中。从jQuery 1.7开始,jQuery将自己定义为一个模块,上面的代码将是有效的。在1.7之前,您可以使用require-jquery.js从require-js加载jquery并将其定义为一个模块。
define( "jquery", [], function () { return jQuery; } );
require(["jquery"], function($) { }
define(['require', 'domReady'], function(require, domReady) {
domReady(function() {
require(['app'], function(app) {
app.initialize();
});
});
});