Use Your Fn jQuery Namespace

By Ryan Florence, published 2010-10-05

Part of the issue Thoughtful jQuery Plugin Development.

Every plugin gets a namespace on the jQuery prototype. If you keep all of your functions, methods, and variables scoped inside the jQuery.fn function, others can’t extend or alter the functionality of your plugin. Instead, take advantage of your block on jQuery street and let other developers take advantage of your plugin.

Hang your members on your $.fn namespace

If we make a tiny change to the plugin discussed in Providing options in jQuery plugins, we make it ridiculously more flexible. Pay attention to how the defaults are assigned in this example.

// ex. 7
(function($){

  $.fn.disables = function(selector, options){
    options = $.extend({}, $.fn.disables.defaults, options);
    
    // ... blah blah blah
    
  };

  $.fn.disables.defaults = {
    attr: 'checked',
    expected: true,
    onChange: function(){}
  };  

})(jQuery);

I’ve placed the defaults on $.fn.disables.defaults instead of just var defaults this time. This object oriented approach exposes the defaults to the developer. Now s/he can change the default behavior of all instances with one block of code, rather than having to do it with every instance.

Consider that across my application I want to add the “disabled” class to the elements when they are disabled. If I var-ed my defaults the developer would have to do this all over the place:

$('#my-checkbox').disables('.group', {
  onChange: function(isEqual, els){
    els[((isEqual) ? 'add' : 'remove') + 'Class']('disabled'); // adds or removes disabled className
  }
});

$('#my-other-checkbox').disables('.group', {
  onChange: function(isEqual, els){
    els[((isEqual) ? 'add' : 'remove') + 'Class']('disabled'); // adds or removes disabled className
  }
});

// all over the place

Some of you are saying “or just store it in a function somewhere.” You’re right, but I still have to define the onChange for each instance. Others might even reach for the source and change the default onChange function.

Since this plugin is more thoughtful, and exposes the defaults on it’s effin’ namespace, I have a better option. I can just change the default without hacking the plugin’s source code.

Overriding default behavior is easy, now

$.fn.disables.defaults.onChange = function(isEqual, els){
  els[((isEqual) ? 'add' : 'remove') + 'Class']('disabled'); // adds or removes disabled className
};

Now I can support some styling in browsers that don’t support the :disabled CSS selector with 3 measly lines of code. If I had 20 instances of disables (which I did), I would have had 4 more lines of code per instance, or 80 lines total of identical code–what a waste. Additionally, I don’t need to worry about forgetting to add the option to an instance here or there. If you’re still not convinced, imagine, now, that we want to change the disabled className to something else, or change the default onChange later. Find and replace only works for a while.

This tip doesn’t just apply to options either. You can put any number of your plugin’s methods on it’s effin’ namespace, giving developers a place to make adjustments without poking your code with a stick.

While this is a huge step in the right direction, if you start hanging everything off of jQuery.fn.namespace.member or adding every method you use as an option with jQuery.fn.namespace.defaults.member, the code starts to suffer from readability and non-brevity. There’s another way to author a plugin: Use objects and then simply add them to the jQuery prototype

Hi, I'm Ryan!

Location:
South Jordan, UT
Github:
rpflorence
Twitter:
ryanflorence
Freenode:
rpflo

About Me

I'm a front-end web developer from Salt Lake City, Utah and have been creating websites since the early 90's. I like making awesome user experiences and leaving behind maintainable code. I'm active in the JavaScript community writing plugins, contributing to popular JavaScript libraries, speaking at conferences & meet-ups, and writing about it on the web. I work as the JavaScript guy at Instructure.