jQuery plugins: the this keyword and its context: beware of the each() loop

jQuery plugins: the this keyword and its context: beware of the each() loop

The this keyword used in jQuery plugin development must be used within its proper context.

When developing jQuery plugins care must be taken with the this keyword. Usually developers think of this keyword as an easy link to the current jQuery object where the plugin's code is executed. However, there are some exceptions.

A common error may arise when defining private methods. Consider the following example:


(function($) {

	$.fn.mySlider = function(options) {
		var that = this;
		var settings = {
			wrapper: 'ul',
			slides: 'li'
		};
		
		options = $.extend(settings, options);
		
		var _setDimensions = function(context) {
			var width = context.width(),
				totalWidth = width * $(options.slides, context).length;
			    $(options.wrapper, context).width(totalWidth);
		};
		
		return that.each(function() {
			_setDimensions(that);
		
		});
	
	
	};

})(jQuery);

This code will work as expected when you have only one instance of the jQuery object referenced by this. But if you have:


$('div.slideshow').mySlider();

the above code will work only on the very first element of the set. The problem lies in the that reference: the each() loop used by jQuery plugins is not a mere design pattern. In fact, its goal is binding your code to all the instances of the jQuery's set selected by your plugin.

If you want to make your private method work on all the instances of the wrapped set, you have to change your code as follows:


return this.each(function() {
	var $context = $(this);
	_setDimensions($context);

});

This code will work on all the instances of the elements contained in the wrapped set because our routine takes place within the each() loop. Inside this loop, the this keyword will always point to the current object of the jQuery's set.