Organize JavaScript and jQuery events — DOM-ready execution

Amr Elgarhy
TreeNodes
Published in
2 min readApr 19, 2012

In complex websites javascript and jquery events can conflict with each other, especially if you are using the same javascript files for different website pages.
There are many techniques to solve this issue, and I found a good solution by following these articles:
Automate firing of onload events
Markup-based unobtrusive comprehensive DOM-ready execution
Extending Paul Irish’s comprehensive DOM-ready execution

But while using this technique I faced an issue, I wanted to call more than one init function on the same page load, for example if I have my page as sections: header, login popup, inner form, footer. And each section needs to have its own init functions which load automatically when this section DOM-ready.

In Extending Paul Irish’s comprehensive DOM-ready execution article
He used the body element to run the selected action in the selected controller

<body data-controller="<%= controller_name %>" data-action="<%= action_name %>">

And since body element is always one in any page, so we can’t call more than one controller action.

I extended this technique to use any html element in the page, something like that:

<i class="initializer" data-controller="<%= controller_name %>" data-action="<%= action_name %>"></i>

Like that i can use this element multiple times in the page for different controllers and actions.
But this required to edit JASON GARBER javascript UTIL function to fit this change.
Using the body element code was:

UTIL = {
exec: function( controller, action ) {
var ns = SITENAME,
action = ( action === undefined ) ? "init" : action;
if ( controller !== "" && ns[controller] && typeof ns[controller][action] == "function" ) {ns[controller][action]();}
},
init: function() {
var body = document.body,
controller = body.getAttribute( "data-controller" ),
action = body.getAttribute( "data-action" );
UTIL.exec( "common" );
UTIL.exec( controller );
UTIL.exec( controller, action );
}
};
$( document ).ready( UTIL.init );
And using my way it required changing the code to be:
var SiteName = SiteName || {};SiteName.Common = {
init: function () {
// generic event bindings
}
};
SiteName.UTIL = {
exec: function (controller, action) {
var ns = SiteName,
action = (action === undefined || action == null) ? "init" : action;
if (controller !== "" && ns[controller] && typeof ns[controller][action] == "function") {
ns[controller][action]();
}
},
init: function () {
SiteName.UTIL.exec("Common");
var initializers = $('.initializer');
$('.initializer').each(function () {
var controller = this.getAttribute("data-controller"),
action = this.getAttribute("data-action");
SiteName.UTIL.exec(controller, action);
});
}
};
$(document).ready(SiteName.UTIL.init);
And as you see in my code I loop on all elements which use class 'initializer' and read/call from them one by one controllers - actions.
By applying this edit, you will be able to assign multiple different controllers in the same page based on the page sections.Download Demo

--

--