Skip to main content

DOM-dependent JS

A.k.a the on_ready manifest.

Explanation

Instead of wrapping all DOM-dependent JS in a $(document).ready callback, PMACS Frontend provides a simpler mechanism for writing and organizing JavaScript that relies on the DOM being ready. In the past, all JavaScript would be merged together into the application.js manifest file, which was included in the page <head>, meaning it was parsed and executed before the page <body> had finished rendering. Since PMACS Frontend now controls the application layout, we have the opportunity to utilize an old tried-and-true technique for managing DOM-dependent JS: we load that JS at the bottom of the <body>.

Configuring the manifests

This requires a second manifest file, on_ready.js. The PMACS Frontend gem is expecting to find a manifest file at app/assets/javascripts/on_ready.js, so you must create this file whether you are utilizing it or not. Then, be sure to include the gem's DOM-dependent JavaScript in this new manifest file:

// file: app/assets/javascripts/on_ready.js

//= require pmacs-frontend/on_ready

If your application.js manifest loads everything in and below its directory through //= require_tree you must stub the on_ready/ directory in your project to prevent its contents from being loaded twice.

// file: app/assets/javascript/application.js

//= require_tree .
//= stub "on_ready"

Usage

Now, you can write whatever JavaScript you need that depends on the presence of the DOM and simply bring it into this manifest file and not application.js (application.js is reserved for DOM-independent JavaScript). Because this manifest file is included at the end of the <body> tag, it is parsed and executed after the DOM has rendered, meaning we don’t have to wrap the JS in callbacks!

You may be wondering if you need to tell Sprockets to precompile on_ready.js. If you're using Sprockets <4, you may be accustomed to something like:

Rails.application.config.assets.precompile += %w( on_ready.js )

This Gem is configured as an engine and so can load its own initializers before the Rails app loads. As a result, this gem has a similar line to declare the manifest a precompile target. If you are using Sprockets >= 4 then you no longer need to declare precompile targets like this. The manifest tree, starting at a new file (app/assets/config/manifest.js) and descending through whatever manifest files you declare, is solely responsible for informing Sprockets on what should be precompiled. In other words, once you get it all set up, Sprockets just pays attention to whatever manifest.js tells it about. Providing separate, application-level configuration for asset business is a thing of the past.f

And if you're using Webpack through Webpacker, you're living in the future and don't have a care in the world.

With your new on_ready.js manifest file properly precompiling and bringing in the gem's DOM-dependent JS, you have everything you need to start writing your application's own DOM-dependent JS (and with the PmacsRouteInfo object that this gem provides, you can also easily write page-specific DOM-dependent JS).