jQuery Plugin Callbacks and Events
I have written a fair few plugins for jQuery for both work and side projects. As any developer should, I am always trying to improve my techniques for creating them so that they are as efficient and maintainable as possible.
Up until recently, my usual technique for callbacks and events would be to include the function in the options that you pass in. For instance, you would setup you plugin as follows:
1 2 3 4 5 6 7 8 9 10 11 | (function($) { $.fn.myPlugin= function(options) { var settings = { setting1: 0, setting2: '' }; //overload default settings if (options) { jQuery.extend(settings, options); } return this.each(function() { ..... |
This would allow you to pass in any number of settings, including callbacks to utilise at runtime:
1 2 3 4 5 | $('#myselector').myPlugin({ setting1:1234, setting2:'somesetting', callback1: function() {} }); |
Yesterday it occurred to me that jQuery had a neat feature that is much better than doing this – custom event binding. jQuery not only allows you to bind the DOM events to elements such as click, focus, keydown etc but because of the way it stores all the bindings, you can bind any number of custom events as well. This means that you can set your events for the plugin as follows:
1 2 3 4 | $('#myselector').myPlugin({ setting1:1234, setting2:'somesetting' }).bind("mycallbackevent", function() {...}); |
Within your plugin you would need to trigger that event like so:
$(this).trigger("mycallbackevent", [somedata]);
This technique also provides a neater alternative to public functions on your plugin. Say you wanted to initialise the plugin when a link is clicked. I would have previously setup a public function in the plugin to do this:
this.init = function() { .. }
and then run it as follows:
$('a').click(function() { $('pluginselector').get(0).init(); }
With custom events you would setup the event inside the plugin as follows:
$(this).bind('init',function() { .. });
and run as follows:
$('a').click(function() { $('pluginselector').trigger('init'); }
Perhaps I have just been writing plugins incorrectly all this time but that seems much better to me.
