When is requireJS done loading all modules
google-analytics, javascript, requirejs
Solution
This question is over two years old, but it was the only relevant question I found on SO when I had the same problem. I eventually found an answer that works for me. Here's some background: I have a dynamically generated page, with multiple and varied numbers of page sections that may include modules loaded by require.js. Picture a page with a variable number tiles for example, and each tile may load scripts using require. Now when all tiles are loaded, I want to run some other javascript. But how do you tell when require.js is done loading everything, including modules that may be loaded as sub modules?
Looking at the require.js code, I see that it contains a registry, which appears to be a list of pending loads and their callbacks. So when the registry is empty, require.js is done loading and done running callbacks. At least it appears that way, and this works for me. Basically at the bottom of the page (below any other calls to require()), I add this 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($) } );
Here I am using jquery because I already have it loaded in the page, but it isn't really necessary. The basic idea is just to check the registry for the default context in requirejs (named "_") and when it is empty, that means requirejs has no pending scripts to load or callbacks to run. This works for my use case anyway.
Problem
I'm wanting to wait for all of my requireJS modules to finish loading before firing an event. Is there an event, or a way to listen for all of my requireJS modules to finish loading? The details: I'm trying to add custom dimensions to my Google Analytics, and then send a pageview. This is easy to do on all pages if I set the same dimensions but in some of my requireJS modules I want to change the dimensions BEFORE the page view. I've got my template javascript which is run on every single page, I want it to do: ``` LISTEN_FOR_MODULES_TO_LOAD(function() { $(document).trigger('set-your-analytics-dimensions-yall'); ga('send', 'pageview'); }); ``` Then on some of my subpages I've got modules doing: ``` $(document).on('set-your-analytics-dimensions-yall', function() { ga('set', 'dimension'); }); ``` I want the flow to be: - Listen for all my modules to finish loading - Ask other modules to set their dimensions and other values - Set pageview The problem is that I have no way to listen for all my requirejs modules to load. Things I've considered: DOM Ready This doesn't work because DOM Ready can fire before or after all JavaScript modules are loaded. window.onload This isn't reliable and can fire multiple times. If an image is added to the page 10 minutes later it can fire again. If an external resource never loads this event will never fire. Is there an options I have missed? Or something I have missed entirely from requireJS?