Permalink
Browse files

added jquery plugin patterns

  • Loading branch information...
1 parent 7c5e30c commit 3e7222d1f707c2ce03e59d973f417c00898cdb78 @shichuan shichuan committed Mar 14, 2012
@@ -7,96 +7,49 @@
<body>
<script>
/*!
- * jQuery UI Widget factory "bridge" plugin boilerplate
- * Author: @erichynds
- * Further changes, additional comments: @addyosmani
+ * jQuery 'best options' plugin boilerplate
+ * Author: @cowboy
+ * Further changes: @addyosmani
* Licensed under the MIT license
*/
- // a "widgetName" object constructor
- // required: this must accept two arguments,
- // options: an object of configuration options
- // element: the DOM element the instance was created on
- var widgetName = function( options, element ){
- this.name = "myWidgetName";
- this.options = options;
- this.element = element;
- this._init();
- }
+ ;(function ( $, window, document, undefined ) {
- // the "widgetName" prototype
- widgetName.prototype = {
+ $.fn.pluginName = function ( options ) {
- // _create will automatically run the first time this
- // widget is called
- _create: function(){
- // creation code
- },
+ // Here's a best practice for overriding 'defaults'
+ // with specified options. Note how, rather than a
+ // regular defaults object being passed as the second
+ // parameter, we instead refer to $.fn.pluginName.options
+ // explicitly, merging it with the options passed directly
+ // to the plugin. This allows us to override options both
+ // globally and on a per-call level.
- // required: initialization logic for the plugin goes into _init
- // This fires when your instance is first created and when
- // attempting to initialize the widget again (by the bridge)
- // after it has already been initialized.
- _init: function(){
- // init code
- },
+ options = $.extend( {}, $.fn.pluginName.options, options );
- // required: objects to be used with the bridge must contain an
- // 'option'. Post-initialization, the logic for changing options
- // goes here.
- option: function( key, value ){
+ return this.each(function () {
- // optional: get/change options post initialization
- // ignore if you don't require them.
+ var elem = $(this);
- // signature: $('#foo').bar({ cool:false });
- if( $.isPlainObject( key ) ){
- this.options = $.extend( true, this.options, key );
+ });
+ };
- // signature: $('#foo').option('cool'); - getter
- } else if ( key && typeof value === "undefined" ){
- return this.options[ key ];
+ // Globally overriding options
+ // Here are our publicly accessible default plugin options
+ // that are available in case the user doesn't pass in all
+ // of the values expected. The user is given a default
+ // experience but can also override the values as necessary.
+ // eg. $fn.pluginName.key ='otherval';
- // signature: $('#foo').bar('option', 'baz', false);
- } else {
- this.options[ key ] = value;
- }
-
- // required: option must return the current instance.
- // When re-initializing an instance on elements, option
- // is called first and is then chained to the _init method.
- return this;
- },
-
- // notice no underscore is used for public methods
- publicFunction: function(){
- console.log('public function');
- },
-
- // underscores are used for private methods
- _privateFunction: function(){
- console.log('private function');
- }
- };
+ $.fn.pluginName.options = {
- // usage:
+ key: "value",
+ myMethod: function ( elem, param ) {
- // connect the widget obj to jQuery's API under the "foo" namespace
- // $.widget.bridge("foo", widgetName);
-
- // create an instance of the widget for use
- // var instance = $("#elem").foo({
- // baz: true
- // });
-
- // your widget instance exists in the elem's data
- // instance.data("foo").element; // => #elem element
-
- // bridge allows you to call public methods...
- // instance.foo("publicFunction"); // => "public method"
+ }
+ };
- // bridge prevents calls to internal methods
- // instance.foo("_privateFunction"); // => #elem element
+ })( jQuery, window, document );
// References
@@ -0,0 +1,130 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <title>JavaScript Patterns</title>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <script>
+ /*!
+ * (jQuery mobile) jQuery UI Widget-factory plugin boilerplate (for 1.8/9+)
+ * Author: @scottjehl
+ * Further changes: @addyosmani
+ * Licensed under the MIT license
+ */
+
+ ;(function ( $, window, document, undefined ) {
+
+ //define a widget under a namespace of your choice
+ //here 'mobile' has been used in the first parameter
+ $.widget( "mobile.widgetName", $.mobile.widget, {
+
+ //Options to be used as defaults
+ options: {
+ foo: true,
+ bar: false
+ },
+
+ _create: function() {
+ // _create will automatically run the first time this
+ // widget is called. Put the initial widget set-up code
+ // here, then you can access the element on which
+ // the widget was called via this.element
+ // The options defined above can be accessed via
+ // this.options
+
+ //var m = this.element,
+ //p = m.parents(":jqmData(role='page')"),
+ //c = p.find(":jqmData(role='content')")
+ },
+
+ // Private methods/props start with underscores
+ _dosomething: function(){ ... },
+
+ // Public methods like these below can can be called
+ // externally:
+ // $("#myelem").foo( "enable", arguments );
+
+ enable: function() { ... },
+
+ // Destroy an instantiated plugin and clean up modifications
+ // the widget has made to the DOM
+ destroy: function () {
+ //this.element.removeStuff();
+ // For UI 1.8, destroy must be invoked from the
+ // base widget
+ $.Widget.prototype.destroy.call(this);
+ // For UI 1.9, define _destroy instead and don't
+ // worry about calling the base widget
+ },
+
+ methodB: function ( event ) {
+ //_trigger dispatches callbacks the plugin user can
+ // subscribe to
+ //signature: _trigger( "callbackName" , [eventObject],
+ // [uiObject] )
+ // eg. this._trigger( "hover", e /*where e.type ==
+ // "mouseenter"*/, { hovered: $(e.target)});
+ this._trigger('methodA', event, {
+ key: value
+ });
+ },
+
+ methodA: function ( event ) {
+ this._trigger('dataChanged', event, {
+ key: value
+ });
+ },
+
+ //Respond to any changes the user makes to the option method
+ _setOption: function ( key, value ) {
+ switch (key) {
+ case "someValue":
+ //this.options.someValue = doSomethingWith( value );
+ break;
+ default:
+ //this.options[ key ] = value;
+ break;
+ }
+
+ // For UI 1.8, _setOption must be manually invoked from
+ // the base widget
+ $.Widget.prototype._setOption.apply(this, arguments);
+ // For UI 1.9 the _super method can be used instead
+ // this._super( "_setOption", key, value );
+ }
+ });
+
+ })( jQuery, window, document );
+
+ //usage: $("#myelem").foo( options );
+
+ /* Some additional notes - delete this section before using the boilerplate.
+
+ We can also self-init this widget whenever a new page in jQuery Mobile is created. jQuery Mobile's "page" plugin dispatches a "create" event when a jQuery Mobile page (found via data-role=page attr) is first initialized.
+
+ We can listen for that event (called "pagecreate" ) and run our plugin automatically whenever a new page is created.
+
+ $(document).bind("pagecreate", function (e) {
+ // In here, e.target refers to the page that was created
+ // (it's the target of the pagecreate event)
+ // So, we can simply find elements on this page that match a
+ // selector of our choosing, and call our plugin on them.
+ // Here's how we'd call our "foo" plugin on any element with a
+ // data-role attribute of "foo":
+ $(e.target).find("[data-role='foo']").foo(options);
+
+ // Or, better yet, let's write the selector accounting for the configurable
+ // data-attribute namespace
+ $(e.target).find(":jqmData(role='foo')").foo(options);
+ });
+
+ That's it. Now you can simply reference the script containing your widget and pagecreate binding in a page running jQuery Mobile site, and it will automatically run like any other jQM plugin.
+ */
+
+
+ // References
+ // http://coding.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/
+ </script>
+ </body>
+</html>
Oops, something went wrong.

0 comments on commit 3e7222d

Please sign in to comment.