Created
September 21, 2012 16:23
-
-
Save raglan-road/3762458 to your computer and use it in GitHub Desktop.
Patterns for building jQuery plugins!
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
// Why plugins? Think about using a plugin when you need a piece of reusable functionality that will be applied to | |
// an element - and potentially many elements - in a given UI. | |
// Resource: http://docs.jquery.com/Plugins/Authoring | |
// The basic plugin boilerplate | |
;(function($){ | |
$.fn.plugin = function(){ | |
// If your plugin needs to be chainable, return this! | |
return this; // this -> reference to calling jQuery Object e.g. $('.foo').plugin() => $('.foo') | |
} | |
}(jQuery)); | |
// $('.foo').plugin(); | |
// $('li').plugin().removeClass('no-plugins-here'); | |
// What about processing multiple items in a selector, like $('li') or $('.foo')? | |
;(function($){ | |
$.fn.plugin = function(){ | |
return this.each(function(){ | |
// Process each item in your jQuery collection | |
}); | |
} | |
}(jQuery)); | |
// $('body, .foo, li').plugin().addClass('pluginified'); | |
// More robust: passing in configuration options! This is meant to run exactly *once*; running multiple times will basically rerun everything. | |
;(function($){ | |
$.fn.plugin = function(opts){ | |
// Always set defaults so callers do not need to pass in an options object | |
var options = { | |
foo: 1, | |
bar: 2, | |
onBeforeInit: null | |
}; | |
$.extend(options, opts); // jQuery magic: Merge default options and user-supplied opts; farthest-right argument takes precendence in the merge. | |
return this.each(function(){ | |
// Maybe we use onBeforeInit to notify subscribers that something's happening... | |
if(typeof options.onBeforeInit === "function"){ | |
options.onBeforeInit(); | |
} | |
// Process each item in your jQuery collection | |
$(this).data('foobar', options.foo + options.bar); | |
console.log(options) | |
}); | |
} | |
}(jQuery)); | |
// $('div').plugin() | |
// $('div').plugin({ foo: 1, bar: 2, newOpt: "hello!"}) | |
// Let's get super-fancy: methods! This is the jQuery UI-ish way of doing things, like $('.some-el').dialog('open') or $('.some-el').dialog('close') | |
;(function($){ | |
"use strict"; | |
// Always set defaults so callers do not need to pass in an options object | |
var options = { | |
foo: 1, | |
bar: 2, | |
onBeforeInit: null | |
}, | |
methods = { | |
// Allow the user to get or set options | |
options: function(key, value){ | |
if(typeof value !== "undefined"){ | |
options[key] = value; | |
} | |
return options[key]; | |
}, | |
// Our default case: initialize the plugin | |
init: function(opts){ | |
// Maybe we use onBeforeInit to notify subscribers that something's happening... | |
if(typeof options.onBeforeInit === "function"){ | |
options.onBeforeInit(); | |
} | |
$.extend(options, opts); | |
return this.each(function(){ | |
// Always bind info to .data()! | |
$(this).data('plugin', $('<div class="plugin">Hi!</div>').appendTo(this).hide()) | |
.bind('click.plugin', function(){ alert('plugin!') }); | |
}); | |
}, | |
// Just an example | |
show: function(){ | |
$(this).data('plugin').show(); | |
console.log('we just showed a fake div!') | |
}, | |
destroy : function(){ | |
// Unbind any events we bound | |
// Clean up any data() we stored | |
// Remove any elements added to page | |
} | |
}; | |
// Note the change! Everything else is "private" due to a closure. | |
$.fn.plugin = function(method){ // User can pass in optional arguments, so the signature is really something like (method,[option, option, ...]) | |
// Did the user pass in a configuration object or a method name? | |
if(method in methods){ | |
// If the user supplied a method, execute it for them. We'll slice off the first argument (method name) in case the user supplied additional parameters. | |
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); | |
} | |
else if(typeof method === "object" || typeof method === "undefined"){ | |
return methods['init'].apply(this, arguments); // Our default case: initialize the plugin | |
} | |
else{ | |
$.error("Method " + method + " does not exist"); | |
} | |
} | |
}(jQuery)); | |
// $('.some-selector').plugin(); | |
// $('.some-selector').plugin({ foo: 42, baz: "hello!", onBeforeInit: function(){ console.log('before!') } }); | |
// $('.some-selector').plugin('options','foo',11); | |
// $('.some-selector').plugin('show'); | |
;(function($){ | |
$.fn.navItemThing = function(){ | |
var show = function(el){ | |
$(el).addClass('visible'); | |
$('#' + $(el).data('flyoutid').show(); | |
} | |
var hide = function(el){ | |
$(el).removeClass('visible'); | |
$('#' + $(el).data('flyoutid').hide(); | |
} | |
return this.each(function(){ | |
// $('.action-button').navItemThing(); | |
$(this).bind('click.navItemThing', function(e){ | |
e.preventDefault(); // ALWAYS!!! | |
// <a href="#" data-flyoutid="foo">^</a> ... <ol id="foo"><li>one</li><li>two</li><li>three</li></ol> | |
if($(this).hasClass('visible'){ show(this); } | |
else{ hide(this); } | |
} | |
}); | |
} | |
}(jQuery)); | |
// $('.action-buttons').navItemThing(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment