Skip to content

Instantly share code, notes, and snippets.

@zhannes
Created July 29, 2011 20:18
Show Gist options
  • Save zhannes/1114637 to your computer and use it in GitHub Desktop.
Save zhannes/1114637 to your computer and use it in GitHub Desktop.
A cleaner approach to jquery plugins. Model one instance of an object to be applied to each element returned in the wrapped set for your plugin. Separate the code for the plugin's functionality from the assignment into the jQuery namespace. Taken from var
(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);
(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);
@amadeusjunqueira
Copy link

thanks for this!

@dey-dey
Copy link

dey-dey commented Oct 26, 2011

dirtft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment