Requirejs domReady插件与Jquery $ {document).ready()?


100

我正在使用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。而RequireJS只会domReady在我已经需要jQuery时增加其他JS的负担。

问题

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

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

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

更明确地说明我的问题:require domReady或之间有什么区别jQuery


4
I am not confident in jquery's dom ready我想将其标记为令人反感:p
Dakait

3
即使在IE上,jQuery的dom ready也完全可靠。每天都有数百万人在不知情的情况下使用它;-)
John Dvorak

1
您是在控制script标记的位置,还是在编写其他人将使用的库/插件(因此,他们控制script标记在标记中的位置)?
TJ Crowder

3
哦,天哪..阅读全文。I am not confident in jquery's dom ready because requirejs is doing its magic.因为,require是在有限的本地范围内封装jquery。那不是重点。(就问题而言)。
Yugal Jindle 2013年

1
谢谢@TJCrowder的编辑。
Yugal Jindle 2013年

Answers:


91

似乎所有关键点都已经实现,但是一些细节却落空了。主要是:

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也会触发任何就绪的回调(您的代码不必在意哪个会先发生。)。


1
美丽,这就是我想要的。合理,得到很好的支持。
Yugal Jindle

很高兴能为您提供帮助:-)
fncomp

@YugalJindle赏金不见了吗?:)
fncomp

我只是在测试你写的东西-你走了!
Yugal Jindle

查看domReady插件代码(github.com/requirejs/domReady/blob/master/domReady.js),我看不出有什么理由需要将其加载为“ domReady!”。而不是'domReady'-您能指出一些导致行为改变的代码吗?
2015年

20

尝试回答您的主要问题:

为什么我们可以使用jquery时requirejs提供domReady插件$(document).ready();

他们确实做了两件事。RequireJS的domReady依赖性表示此模块要求DOM在运行之前必须完全加载(因此,可以根据需要在应用程序的任意数量的模块中找到$(document).ready()它),而在DOM为加载完成。

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

同时,如果我有一个事件需要在DOM准备就绪时立即发生,则该$(document).ready()事件将成为后续事件,因为只要您依赖于代码,则该事件并不特别取决于RequireJS完成加载模块称呼它为满足。

还值得考虑的是,您不必将RequireJS与jQuery一起使用。然后,任何需要DOM访问(但不依赖jQuery)的库模块仍然有用domReady


domReady不是requirejs的依赖项。如果您domReady用于DocumentReady事件,则它将是代码的依赖项。另外,您似乎感到困惑。
Yugal Jindle 2013年

1
好的答案,并且是许多开发人员常常不知道的微妙之处的重要提示(包括我自己;-))。
Golo Roden

1
尤加尔(Yugal),我指的domReady是依赖项,因为这是它的用法。不是作为RequireJS的依赖项,而是作为使用它的模块的依赖项。也许我应该在文字中更清楚地说明这一点,您对此有何建议?
GertSønderby'13

请参阅有关问题的Update2。可能是我们不在同一页面上。
Yugal Jindle

Yugal,如果您使用MooTools怎么办?Qooxdoo?没有jQuery吗?RequireJS不是与jQuery结婚的,尽管它们确实可以很好地协同工作。
GertSønderby2013年

6

按出现顺序回答子弹:

  • 他们俩确实完成了同一件事
  • 如果您出于某种原因对jquery有所保留,请使用domReady
  • 正确,所以只使用jQuery
  • 因为不是每个人都使用jQuery
  • 我同意,只需使用jQuery
  • 插件按定义“满足需求”。
  • 跨浏览器ajax并不是问题。跨网域?可能有,如果没有,则不需要进食。
  • , -, -, - 好

归结为它,您就是在想这个。这是一种在domReady上执行javascript的机制。如果您没有jQuery,我会推荐domReady插件。由于您具有jQuery,因此不必加载更多脚本来执行已经可用的操作。

清晰度更新

domReady插件收集文档“就绪”时要调用的函数。如果已加载,则它们将立即执行。

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

这意味着他们实际上可以做完全相同的事情。


0

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

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

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.');
    });
});

1
我怀疑,如果您的依赖项列表中包含所有模块,那么所有模块都将被提取并进入内存。发布该jquery在执行之前收集dom.ready实例。
Yugal Jindle

如果DOM已经准备就绪,则的回调$(document).ready将立即运行。
Danyal Aytekin 2014年

-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');
        });
    });
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.