Proper handling of event bindings in jQuery plugin
JQuery Offers simple way to create plugins, that maintains its state and offers same flexibility as the core plugins. Check this article - Essential jQuery Plugin Patterns by Addy Osmani that covers most of the patterns used for creating a plugin. I'm sure you would say Wow
after reading it and also appreciate how jQuery simplifies plugin creation pattern.
While creating a plugin, I found it hard to find a proper way to bind and unbind events from the objects in global scope like window
, document
.
For e.g., You want your plugin to refresh its styling or component interaction based on screen size, you will bind your logic like below
$(window).on('resize', doSomeChanges);
Above code works fine, but becomes a challenge when you decide to unbind its event. $(window).off('resize');
will remove all events bound to 'resize' event including the ones created by other plugins/code.
Option 1:
You can go ahead and pass the function again to unbind the event as follows
$(window).off('resize', doSomeChanges);
Well above will work flawlessly if your plugin appears once in that page. What happens if it is place more than once ? A simple call to 'off' particular event from window object in a plugin instance will unbind it from all instances of your plugin in that page.
Option 2:
jQuery comes up with event namespacing that helps to remove the events that you have bound through your plugin, without impacting others. 'myNamespace' is just a simple name, it can be anything specific to your plugin.
// Bind
$(window).on('resize.myNamespace', doSomeChanges);
// Unbind
$(window).off('resize.myNamespace');
Simply removes just the event in the specified namespace. but this still doesn't solve the issue when more that one instance is used in the page.
Option 3:
You can properly subspace your namespaces with unique names to unbind just those like below.
In your plugin, you can generate a unique eventNamespace and then bind or unbind using it as follows
$.fn.myPlugin = function(option){
this.eventNamespace = '.id-' + random-unique-number;
// Bind
$(window).on('resize.myPlugin'+ this.eventNamespace, doSomeChanges);
// Unbind
$(window).off('resize.myPlugin' + this.eventNamespace);
}
That's all now your plugin event binding will be more specific and proper.
Option 4:
When using jQuery UI, you can modify the unique Id generation as follows that helps you to add a unique id to your plugin element as well as get a unique name / namespace
var table = $(this); // Your plugin object
table = table.uniqueId(); // Generate unique element id if not present
var namespace = table.attr('id');
Happy jQuerying