ollit ollit - 4 months ago 17
Javascript Question

jQuery global/local event execution order

I have a panel widget with a button. Clicking the button should execute some global actions related to all such widgets and after that execute some local actions related to this widget instance only. Global actions are binded in a separate javascript file by CSS class like this:

var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});

return {
init: function ()
{
handleWidgetButton();
}
};
}
}();

jQuery(document).ready(function()
{
App.init();
});


And in the html file local script is like this:

$("#widgetBtn1234").click(function (e)
{
// do smth local
});


Currently local script is executed first and global only after while I want it to be the opposite. I tried to wrap local one also with document.ready and have it run after global but that doesn't seem to change the execution order. Is there any decent way to arrange global and local jQuery bindings to the same element?

Answer

The problem you're having comes from using jQuery's .ready() function to initialize App, while you seem to have no such wrapper in your local code. Try the following instead:

var App = function ()
{
    var handleWidgetButton = function ()
    {
        $('.widgetBtn').on('click', function (e)
        {
            // do smth global
        });

        return {
            init: function ()
            {
                handleWidgetButton();
            }
        };
    }
}();

$(function() 
{
    App.init();
});

Then in your local JS:

$(function() {
    $("#widgetBtn1234").click(function (e)
    {
        // do smth local
    });
});

Note that $(function(){}) can be used as shorthand for $(document).ready(function(){});. Also, make sure your JS file is located before your local JS, as javascript runs sequentially.

Alternatively, you can use setTimeout() to ensure everything's loaded properly:

(function executeOnReady() {
    setTimeout(function() {
        // Set App.isInitialized = true in your App.init() function
        if (App.isInitialized) runLocalJs();
        // App.init() hasn't been called yet, so re-run this function
        else executeOnReady();
    }, 500);
})();
function runLocalJs() {
    $("#widgetBtn1234").click(function (e)
    {
        // do smth local
    });
};
Comments