requireJS何时完成所有模块的加载

4
我希望在触发事件之前,等待所有的requireJS模块都完成加载。是否有一个事件或者一种方法可以监听所有的requireJS模块是否已经加载完成?
细节如下:
我想要添加自定义维度到我的Google Analytics并发送页面浏览量。如果我在所有页面上设置相同的维度,则很容易实现。但是,在某些requireJS模块中,我希望在页面浏览量之前更改这些维度。
我有我的模板JavaScript代码,在每个页面上都会运行。我想要让它执行以下操作:
LISTEN_FOR_MODULES_TO_LOAD(function() {
  $(document).trigger('set-your-analytics-dimensions-yall');
  ga('send', 'pageview');
});

然后,在我的一些子页面上,我有一些执行以下操作的模块:

$(document).on('set-your-analytics-dimensions-yall', function() {
  ga('set', 'dimension');
});

我希望流程如下:
  1. 等待所有模块完成加载
  2. 请求其他模块设置它们的尺寸和其他值
  3. 设置页面视图
问题在于我没有办法监听我的requirejs模块是否都已经加载完毕。
我考虑过的事情:
这个方法不可行,因为DOM Ready 可能会在所有JavaScript模块加载之前或之后触发。
这种方法不可靠并且可能会多次触发。如果10分钟后页面添加了一张图片,它可能会再次触发。如果外部资源永远无法加载,此事件将永远不会触发。
我有遗漏的选项吗?或者requireJS 中有我错过的东西吗?

1
当模块可以在运行时包含其他模块时,你怎么可能知道何时所有模块都已加载? - ssube
创建一个模块,该模块需要配置中的每个其他模块。当该模块加载时,您将知道所有其他内容都已完成加载。 - idbehold
我认为Google Analytics是异步加载的。有一个叫做async.js的插件,我曾经用它来加载Google地图API。我不需要其他东西,只需将代码放在define块内,当Google API加载完成时,它将被执行。希望这能解决你的问题,因为我对GA在你的代码中如何加载并不确定。 - Linh Pham
1个回答

4
这个问题已经超过两年了,但是当我遇到同样的问题时,这是我在SO上找到的唯一相关问题。最终我找到了一个适合我的答案。以下是一些背景信息:我有一个动态生成的页面,其中包含多个不同数量的页面部分,其中可能包括通过require.js加载的模块。想象一下一个具有可变数量瓷砖的页面,每个瓷砖都可以使用require来加载脚本。现在当所有瓷砖都加载完毕后,我想运行一些其他的javascript代码。但是如何告诉require.js已经完成了所有加载,包括可能作为子模块加载的模块呢?
查看require.js的代码,我发现它包含一个注册表,该注册表似乎是一个待处理的加载列表及其回调函数。所以当注册表为空时,require.js已完成加载并完成运行回调。至少看起来是这样,对我而言它有效。基本上,在页面底部(在任何其他对require的调用之后),我添加了以下javascript代码:
function run_final_action($) {
    if ($.isEmptyObject(require.s.contexts._.registry)) {
        do_final_action();
    }
    else {
        setTimeout(run_final_action, 100);
    }
}
require( ['jquery'], function ($) { run_final_action($) } );

我在这里使用jQuery,因为它已经加载到页面上了,但实际上并不是必须的。基本思路就是检查requirejs中默认上下文(命名为“_”)的注册表,当它为空时,这意味着requirejs没有要加载的挂起脚本或回调函数。总之,在我的用例中这是有效的。


标记为正确答案以帮助未来的用户。 - bzmw
setTimeout(run_final_action, 100, $); 否则第二次迭代将没有 $ 作为参数并且会崩溃。 - DWils

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接