102

我正在使用 RequireJS 并且需要在准备好的 DOM 上初始化一些东西。现在,RequireJS 提供了domReady插件,但是我们已经有了 jQuery $(document).ready(),因为我需要 jQuery,所以我可以使用它。

所以我有两个选择:

  1. 使用domReady插件:

    require(['domReady'], function (domReady) {
        domReady(function () {
            // Do my stuff here...
        });
    });
    
  2. 使用$(document).ready()

    $(document).ready(function() {
        // Do my stuff here...
    });
    

我应该选择哪一个,为什么?

这两个选项似乎都按预期工作。我对 jQuery 没有信心,因为 RequireJS 正在发挥它的魔力。也就是说,由于 RequireJS 会动态添加脚本,我担心 DOM 准备好可能会在所有动态请求的脚本加载之前发生。domReady然而,当我已经需要 jQuery 时,RequireJS 会增加额外 JS 的负担。

问题

  • domReady当我们可以拥有 jQuery 的时候,为什么 RequireJS 提供了一个插件$(document).ready();?我没有看到包含另一个依赖项的任何好处。
  • 如果它只是为了满足需求,那么为什么不为跨浏览器 AJAX 提供一个呢?

据我所知,domReady在文档准备好后不会获取或执行需要的模块,您也可以使用 jQuery 执行相同的操作:

require(['jQuery'], function ($) {
    $(document).ready(function () {
        // Do my stuff here...
    });
});

为了更清楚地说明我的问题: requires or 和有什么区别?domReadyjQuery

4

5 回答 5

93

似乎所有的关键点都已经被击中,但一些细节却漏掉了。主要是:

domReady

它既是插件又是模块。如果您将它包含在带有尾随的需求数组中,那么!您的模块在与 DOM 交互“安全”之前不会执行:

define(['domReady!'], function () {
    console.info('The DOM is ready before I happen');
});

注意加载和执行是不同的;您希望所有文件尽快加载,这是对时间敏感的内容的执行。

如果省略!,那么它只是一个普通的模块,恰好是一个函数,它可以接受一个在 DOM 可以安全交互之前不会执行的回调:

define(['domReady'], function (domReady) {
    domReady(function () {
        console.info('The DOM is ready before I happen');
    });
    console.info('The DOM might not be ready before I happen');        
});

使用 domReady 作为插件时的优势

依赖于一个模块的代码又依赖于domReady!一个非常显着的优势:它不需要等待 DOM 准备好!

假设我们有一个代码块 A,它依赖于一个模块 B,它依赖于domReady!. 在 DOM 准备好之前,模块 B 不会完成加载。反过来,A 在 B 加载之前不会运行。

如果您要domReady在 B 中用作常规模块,则 A 还需要依赖domReady,并将其代码包装在domReady()函数调用中。

此外,这意味着 与domReady!享有同样的优势$(document).ready()

关于 domReady 和 $(document).ready() 之间的区别

两者都以基本相同的方式嗅探 DOM 是否/何时准备好。

重新担心 jQuery 在错误的时间触发

即使 DOM 在 jQuery 之前加载,jQuery 也会触发任何就绪回调(您的代码不应该关心哪个先发生。)。

于 2013-03-20T06:07:25.450 回答
20

尝试回答您的主要问题:

当我们可以拥有 jquery 时,为什么要requirejs提供插件?domReady$(document).ready();

他们做两件不同的事情,真的。RequireJS 的domReady依赖表示该模块需要在运行之前完全加载 DOM(因此,如果您愿意,可以在应用程序中的任意数量的模块中找到),而$(document).ready()当 DOM 运行时会触发其回调函数加载完成。

差异可能看起来很微妙,但请考虑一下:我有一个模块需要以某种方式耦合到 DOM,所以我可以在模块定义时依赖并耦合它,或者在它的末尾domReady放下 a$(document).ready()带有对模块初始化函数的回调。我称第一种方法更清洁。

同时,如果我有一个事件需要在 DOM 准备好时立即发生,那么该$(document).ready()事件将是首选,因为这并不特别依赖于 RequireJS 是否完成加载模块,只要你的代码依赖调用它从被满足。

同样值得考虑的是,您不一定将 RequireJS 与 jQuery 一起使用。任何需要 DOM 访问(但不依赖 jQuery)的库模块仍然可以通过使用domReady.

于 2013-03-12T14:40:11.463 回答
6

按出现顺序回答你的子弹:

  • 他们都完成了同样的事情
  • 如果您出于某种原因对 jquery 有所保留,请使用 domReady
  • 正确,所以只需使用 jQuery
  • 因为不是每个人都使用 jQuery
  • 我同意,只需使用 jQuery
  • 根据定义,插件“满足需求”。
  • 跨浏览器 ajax 不是一回事。跨域?可能有,如果没有,则无需喂食。
  • , -, -, - 行

当它归结为它时,你想多了。这是一种在 domReady 上执行 javascript 的机制。如果你没有 jQuery,我会提倡 domReady 插件。既然你有 jQuery,那么不要加载更多的脚本来做一些已经可用的事情。

清晰度更新

domReady 插件收集在文档“就绪”时调用的函数。如果它已经加载,那么它们会立即执行。

JQuery 收集函数并将延迟对象绑定到“准备就绪”的 dom。当 dom 准备好时,延迟对象将被解析并且函数将被触发。如果 dom 已经“准备好”,那么 deferred 将已经被解析,因此该函数将立即执行。

这意味着他们有效地做完全相同的事情。

于 2013-03-20T02:51:42.630 回答
0

在对带有多个模块的 requirejs 进行了一些试验之后,我建议使用domReady

我注意到当 requirejs 加载多个模块时,不会调用与$(document).ready(...)关联的函数。我怀疑 dom 在执行所有 requirejs 代码之前就准备好了,并且在它与用户定义的函数(即在主模块代码中)绑定之前调用了 jquery 就绪回调处理程序。

require(['jquery',
    'underscore',
    'text!some_template.html',
    './my_module_1',
    './my_module_2',
    'domReady',
    'other_dependency_1',
    'other_dependency_2'
    ], function($, _, someTemplate, myModule1, myModule2, domReady) {

    $(document).ready(function() {
        console.info('This might never be executed.'); 
        console.info('Dom might get ready before requirejs would load modules.');
    });

    domReady(function () {
        console.info('This runs when the dom gets ready and modules are loaded.');
    });
});
于 2013-07-23T12:21:09.380 回答
-1

我发现我这样做是作为主条目的一部分,这样可以保证我的所有 javascript 都准备好 DOM 并且加载了 jquery。不确定这有多好,欢迎任何反馈,但这是我的 main.js:

require(['domReady!'], function(domReady){
    console.log('dom is ready');
    require(['jquery', 'bootstrap'], function(){
        console.log('jquery loaded');
        require(['app'], function(app){
            console.log('app loaded');
        });
    });
});
于 2015-08-12T02:35:41.370 回答