-
-
Save amadeusjunqueira/1118865 to your computer and use it in GitHub Desktop.
A cleaner approach to jquery plugins. Separate the code for the plugin's functionality from the assignment into the jQuery namespace. Taken from various articles/presos by Alex Sexton and Paul Irish, and #jquery IRC chats. With enthusiasm for Object.creat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function( $ ){ | |
/* | |
A cleaner approach to jquery plugins. Separate the code for the plugin's functionality from | |
the assignment into the jQuery namespace. | |
Taken from various articles/presos by Alex Sexton and Paul Irish, and #jquery IRC chats. | |
With enthusiasm for Object.create() toned down after http://news.ycombinator.com/item?id=2594521 | |
*/ | |
/* | |
Approach 1 | |
Most common. Not so easy on the eyes. | |
Nested anonymous functions and loops galore | |
*/ | |
$.fn.fader = function ( options ) { | |
var opts = $.extend({}, $.fn.pluginname.defaults, options); | |
if( this.length ) { | |
return this.each(function(){ | |
if( $(this).find('li').length ){ | |
$(this).find('li').each(function(){ | |
/* ... more stuff ... */ | |
}); | |
} | |
}); | |
} | |
}; | |
/* | |
Approach 2 | |
Detach plugin functionality from plugin definition. | |
Better, model the plugin's functionality as a **class** | |
( object, whatevs ). Init one new object for each element | |
your plugin is acting on. | |
*/ | |
var Fader = function ( el ){ | |
// ... do some validation | |
this.$el = el; | |
this.init(); | |
}; | |
Fader.prototype = { | |
init: function (){}, | |
otherMethod: function (){} | |
}; | |
$.fn.fader = function () { | |
if( !this.length ){ return this; } | |
return this.each(function(){ | |
new Fader( $(this) ); | |
}); | |
}; | |
/* | |
Approach 2a | |
Depending on your feelings about Object.create() | |
vs new F(), define an object literal with methods. | |
Pass it to Object.create() when iterating | |
over set of elements. | |
*/ | |
var Fader2 = { | |
init: function (){}, | |
otherMethod: function (){} | |
}; | |
/* with Object.create */ | |
$.fn.fader2 = function () { | |
if( !this.length ){ return this; } | |
return this.each(function(){ | |
var myFader = Object.create( Fader ); | |
myFader.init( $(this) ); | |
}); | |
}; | |
/* | |
Approach 3 | |
Uses options. Completely detach | |
the plugin definition from the assignment | |
into the jQuery plugin namespace | |
*/ | |
var Fader = function ( el, options ){ | |
// validate | |
this.$el = el; | |
$.extend( this.options, options ); | |
this.init(); | |
}; | |
Fader.prototype = { | |
init: function (){}, | |
options: { | |
duration: 1000, | |
fadeToOpacity: .3 | |
} | |
}; | |
var faderPlugin = function ( options ) { | |
if( !this.length ){ return this; } | |
return this.each(function(){ | |
if( options ) { | |
var myFader = new Fader( $(this), options ); | |
} else { | |
var myFader = new Fader( $(this) ); | |
} | |
// Save the instance of the object in the element's data store | |
$(this).data('fader', myFader ); | |
}); | |
}; | |
$.fn.fader = faderPlugin; | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($){ | |
/** | |
* @class Binds a text value to focus and blur events. Commonly | |
* used for UI elements like search boxes, text input fields. Useful | |
* for adding place holder text in browsers that don't support HTML5 | |
* 'placeholder' attribtute. | |
* | |
* @constructor | |
* Configure your instances | |
*/ | |
var PlaceholderText = function ( elem, options ) { | |
if ( !elem ){ return false; } | |
if ( !options ){ return false; } | |
/* slim constructor that mostly | |
calls other methods | |
*/ | |
// bunch of validations | |
if ( this.before( elem ) && this.configure( options ) ){ | |
this.attachEvents(); | |
} | |
}; | |
PlaceholderText.prototype = { | |
options: {}, | |
before: function ( elem ) { | |
if( elem.jquery /* is jquery object? */ ){ | |
this.$elem = elem; | |
return true; | |
} else if( elem.tagName /* is dom element? */ ) { | |
// make it a jquery object | |
this.$elem = $(elem); | |
return true; | |
} else { | |
return false; | |
} | |
}, | |
configure: function ( options ) { | |
/* only proceed if it's an | |
* input tag or text area | |
* */ | |
if ( this.$elem.is('input') || this.$elem.is('textarea') ){ | |
$.extend( this.options, options ); | |
return true; | |
} else { | |
return false; | |
} | |
}, | |
attachEvents: function () { | |
this.$elem.bind('blur', $.proxy(this.blurHandler, this) ); | |
this.$elem.bind('focus', $.proxy(this.focusHandler, this) ); | |
}, | |
blurHandler: function ( e ) { | |
if( this.$elem.val() === '' ){ | |
this.$elem.val( this.options.text ); | |
} | |
}, | |
focusHandler: function ( e ){ | |
if( this.$elem.val() === this.options.text ){ | |
this.$elem.val(''); | |
} | |
} | |
}; | |
/* Code that instantiates your 'class' (object), defined above, | |
* once for each element in jQuery wrapped set | |
*/ | |
var placeHolderTextPlugin = function ( options ) { | |
if( !this.length ) { return this; } | |
return this.each(function () { | |
var placeHolder = new PlaceholderText( $(this), options ); | |
$(this).data('placeHolderText', placeHolder ); | |
}); | |
}; | |
// attach plugin | |
$.fn.placeHolderText = placeHolderTextPlugin; | |
// call it like | |
$(function () { | |
$('input').placeHolderText({ text: 'Search' }); | |
}); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment