Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind to all namespaces of custom jquery event

Tags:

jquery

I'm trying to listen for a custom event but I would like to effectively 'ignore' the fact that it's namespaced or somehow listen to all namespaces without defining them individually.

$('#test').on('custom', ...);

$('#test').trigger('custom.namespace1');
$('#test').trigger('custom.namespace2');

The reason I want to be able to do this is because I have multiple ui plugins that fire events when they are hidden/shown. These events are mainly used internally but are namespaced so they don't collide with each other. However I would also just like to know when a particular ui element is hidden, independent of its source to perform other cleanup logic.

In the above example, nothing will happen because the trigger events are namespaced. Can I listen to all namespaces with something to the effect of custom.*?

Fiddle demonstrating the problem.

Thanks

Edit

Even something like this would be desirable but still can't get it to work

$('#test').on('custom.global', log);

$('#test').trigger('custom.global.namespace1');
$('#test').trigger('custom.global.namespace2');

Fiddle

like image 880
jschr Avatar asked Sep 25 '12 20:09

jschr


1 Answers

Try triggerAll instead of trigger:

(function($) {
    $.fn.triggerAll = function(topics, data, delimiter) {
        return this.each(function() {
            var $this = $(this), chain = [], t = '';
            delimiter = (delimiter || '.');
            // rebuild chain
            $.each(topics.split(delimiter), function(i,n) {
                t += (i == 0 ? '' : delimiter) + n;
                chain.push(t);
            });

            // append/prepend original topic?
            data = (data || []);
            data.push(topics);
            $.each(chain, function(i,t) {
                $this.trigger(t, data);
            });
        });
    };
})(jQuery);

Granted, due to how jQuery handles triggering namespacing, triggering the "root" event actually fires the namespaced versions, so to get what you expect you'd need to use another character for the delimiter, like /, and then declare your events like:

var $o = $('#whatever');
// this will be triggered for all events starting with 'root'
$o.on('root', function () { console.log(Array.prototype.slice.call(arguments, 0)); });
// some arbitrary way to fire custom events
$o.on('click', function () {
    $o.triggerAll('root/custom1/subA', ['1st', '2nd'], '/');
    $o.triggerAll('root/custom2', [3, 4, 5], '/');
});

Example in this fiddle

like image 98
drzaus Avatar answered Sep 19 '22 22:09

drzaus