Created
September 24, 2013 01:05
-
-
Save pospi/6679084 to your computer and use it in GitHub Desktop.
Boilerplate code for wrapping up a JavaScript object / class into a jQuery plugin
This file contains hidden or 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
/** | |
* A jquery plugin wrapper for a pure JavaScript class | |
* | |
* This will automatically give us the following: | |
* | |
* - a constructor for our class using $('my.selector').myClass() | |
* - automatic method access to the class's instance functions via syntax | |
* $('my.selector').myClass('funcName', arg1, arg2, ...argN); | |
* - automatic property access of all the class's internal properties. Both this | |
* and the above can assist greatly with third-party code integration | |
* - neater memory usage due to use of prototype functions and proper OO rather | |
* than closures recreating functions in memory each time | |
* - portability (if desired) of our class' internal code away from | |
* framework-dependant code, to allow quick porting to other libraries | |
* | |
* Just replace all instances of 'CHANGEME' to use | |
* | |
* @author Sam Pospischil <[email protected]> | |
*/ | |
$.fn.CHANGEME = function(func) { | |
var t = this; | |
var classStorageKey = 'CHANGEME'; | |
var myObject = t.data(classStorageKey); | |
// constructor to create an object and bind it to our elements | |
var init = function (options) { | |
t.data(classStorageKey, new CHANGEME(t, options)); | |
}; | |
// Run the appropriate behaviour | |
if (func != undefined && myObject != undefined) { | |
if (typeof myObject[func] == 'function') { | |
// object function call | |
return myObject[func].apply( myObject, Array.prototype.slice.call( arguments, 1 )); | |
} else { | |
// intance variable request | |
return myObject[func]; | |
} | |
} else if (typeof func === 'object' || !func ) { | |
// create a new object, optionally passing options map | |
init.apply( t, arguments ); | |
return t; | |
} else { | |
$.error( 'Method ' + func + ' does not exist in CHANGEME' ); | |
} | |
}; | |
/** | |
* And here we go again, but this time with the addition that it | |
* works when run on a jquery object matching multiple elements. | |
* - Constructors are run on all elements in the set | |
* - When run on a single element, works exactly as above | |
* - Property access returns an array in the order of the jQuery set | |
* - Method access either chains when no results are returned, or returns | |
* an array of return values when the method in question has a return value | |
*/ | |
$.fn.CHANGEME = function(func) { | |
var args = arguments; | |
var classStorageKey = 'CHANGEME'; | |
// constructor to create an object and bind it to our elements | |
var init = function (options) { | |
this.data(classStorageKey, new CHANGEME(this, options)); | |
}; | |
var fnCall = false, // function calls can either chain when no results are returned or return arrays of results | |
results = [], | |
args = arguments; | |
this.each(function() { | |
var t = $(this); | |
var myObject = t.data(classStorageKey); | |
// Run the appropriate behaviour | |
if (func != undefined && myObject != undefined) { | |
if (typeof myObject[func] == 'function') { | |
// object function call | |
fnCall = true; | |
results.push(myObject[func].apply( myObject, Array.prototype.slice.call( args, 1 ))); | |
return true; | |
} else { | |
// intance variable request | |
results.push(myObject[func]); | |
return true; | |
} | |
} else if (typeof func === 'object' || !func ) { | |
// create a new object, optionally passing options map | |
init.apply( t, args ); | |
return true; // continue creating for each matched element | |
} else { | |
$.error( 'Method ' + func + ' does not exist in CHANGEME' ); | |
} | |
}); | |
// if the results from all function calls are undefined, there are no results! | |
if (fnCall) { | |
var allUndef = true; | |
for (var i = 0; i < results.length; i++) { | |
if (typeof results[i] != 'undefined') { | |
allUndef = false; | |
break; | |
} | |
} | |
if (allUndef) { | |
results = []; | |
} | |
} | |
return results.length ? (results.length == 1 ? results[0] : results) : this; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment