Currently I am using a single .js file for a whole project (plus included libraries). Only occasionally I split the file into multiple files (i.e. front vs back end sections). In the file(s) I attach events (and other functionality) inside of a single jQuery ready event handler using jQuery selectors:
$(document).ready(function() {
$('#an_element_on_homepage').click(function() {
// do something
});
// ...
// A lot of similar code here
// ...
$('.elements_on_homepage_and_contact_page').click(function() {
// do something
});
});
This is perfectly fine and working, but on a larger project there could be a lot of code executing unnecessarily as some events are needed only at specific pages or there could be id/class collisions between different pages. What is the best practice to avoid the problems and still preserve easy maintainability of the JavaScript and HTML code?
I can think of 2 solutions:
-
Split .js file into multiple files and on every page choose only the files needed. However, it could be hard to distribute the event attachments properly and could cause problems in caching the scripts on client side.
-
Wrap the event attachments in functions and call them from a HTML code only where needed. Something like:
function attachClickOnElementOnHomepage() { $('#an_element_on_homepage').click(function() { // do something }); }And after in HTML:
<div id="an_element_on_homepage"></div> <script type="text/javascript">attachClickOnElementOnHomepage();<script>However, I have a feeling this is also not the best solution possible.
Can you think of another/better solutions?
Solution 1. is, as you say, not particularly efficient with regards to HTTP roundtrips, although you can probably choose to ignore that concern if you’re making an internal application.
Solution 2. just looks like a roundabout way of inline event handler registrations.
The pattern I use is one JS file that has any code I want to reuse as a project-specific “library” – there’s rarely enough of it to warrant splitting it up. And one JS file per unit of server-side code – MVC controller, stand-alone Wicket control – that implements only page-specific behaviour, or wires up to the reusable code. This file is usually named after the controller.
The advantages:
A possible downside is that some code may be repeated between the page-specific scripts, but that’s the cost of separating mechanism from policy. This mostly happens to me for trivial code like setting up jQuery UI buttons or Chosen selectboxes; since they share a common theme, my solution was to roll these up into a single JS file for “ui enhancements”.
You could also look into tooling that will combine fine-grained maintainable javascripts into easier to load ones as a build step; for a large project where the performance gains matter, the effort in maintaining this might not be overkill. The specifics would depend on what your other tooling is, a fallback solution could be as simple as a shellscript that calls the command-line version of jsmin.