Skip to content Skip to sidebar Skip to footer

A Template For A Jquery Plugin With Options And Accessible Methods?

I am want to build a plugin with accessible methods and options, this for a complex plugin. I need the methods to be accessible outside the plugin because if somebody ads something

Solution 1:

An alternative:

varPlugin = function($self, options) {
  this.$self = $self;
  this.options = $.extend({}, $.fn.plugin.defaults, options);
};

Plugin.prototype.display = function(){
  console.debug("Plugin.display");
};

Plugin.prototype.update = function() {
  console.debug("Plugin.update");
};

$.fn.plugin = function(option) {
  var options = typeof option == "object" && option;

  returnthis.each(function() {
    var $this = $(this);
    var $plugin = $this.data("plugin");

    if(!$plugin) {
      $plugin = newPlugin($this, options);
      $this.data("plugin", $plugin);
    }

    if (typeof option == 'string') {
      $plugin[option]();
    } else {
      $plugin.display();
    }
  });
};

$.fn.plugin.defaults = {
  propname: "propdefault"
};

Usage:

$("span").plugin({
  propname: "propvalue"
});

$("span").plugin("update");

This absurdly resembles the Twitter Bootstrap's JavaScript template. But, it wasn't completely taking from there. I have a long history of using .data().

Don't forget to wrap it appropriately.

Solution 2:

If you want to use the plugin like this:

// Init plugin
$('a').myplugin({
    color: 'blue'
});

// Call the changeBG method
$('a').myplugin('changeBG')
    // chaining
    .each(function () {
        // call the get method href()console.log( $(this).myplugin('href') );
    });

or if you need independent Plugin instance per element:

$('a').each(function () {
    $(this).myplugin();
});

you will want to setup your plugin like this:

/*
 *  Project: 
 *  Description: 
 *  Author: 
 *  License: 
 */// the semi-colon before function invocation is a safety net against concatenated// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined) {

    // undefined is used here as the undefined global variable in ECMAScript 3 is// mutable (ie. it can be changed by someone else). undefined isn't really being// passed in so we can ensure the value of it is truly undefined. In ES5, undefined// can no longer be modified.// window is passed through as local variable rather than global// as this (slightly) quickens the resolution process and can be more efficiently// minified (especially when both are regularly referenced in your plugin).var pluginName = "myplugin",
        // the name of using in .data()
        dataPlugin = "plugin_" + pluginName,
        // default options
        defaults = {
            color: "black"
        };

    functionprivateMethod () {
        console.log("private method");
    }

    // The actual plugin constructorfunctionPlugin() {
        /*
         * Plugin instantiation
         *
         * You already can access element here
         * using this.element
         */this.options = $.extend( {}, defaults );
    }

    Plugin.prototype = {

        init: function ( options ) {

            // extend options ( http://api.jquery.com/jQuery.extend/ )
            $.extend( this.options, options );

            /*
             * Place initialization logic here
             */this.element.css( 'color', 'red' );
        },

        destroy: function () {
            // unset Plugin data instancethis.element.data( dataPlugin, null );
        },

        // public get methodhref: function () {
            returnthis.element.attr( 'href' );
        },

        // public chaining methodchangeBG: function ( color = null) {
            color = color || this.options['color'];
            returnthis.element.each(function () {
                // .css() doesn't need .each(), here just for example
                $(this).css( 'background', color );
            });
        }
    }

    /*
     * Plugin wrapper, preventing against multiple instantiations and
     * allowing any public function to be called via the jQuery plugin,
     * e.g. $(element).pluginName('functionName', arg1, arg2, ...)
     */
    $.fn[pluginName] = function ( arg ) {

        var args, instance;

        // only allow the plugin to be instantiated onceif (!( this.data( dataPlugin ) instanceofPlugin )) {

            // if no instance, create onethis.data( dataPlugin, newPlugin( this ) );
        }

        instance = this.data( dataPlugin );

        /*
         * because this boilerplate support multiple elements
         * using same Plugin instance, so element should set here
         */
        instance.element = this;

        // Is the first parameter an object (arg), or was omitted,// call Plugin.init( arg )if (typeof arg === 'undefined' || typeof arg === 'object') {

            if ( typeof instance['init'] === 'function' ) {
                instance.init( arg );
            }

        // checks that the requested public method exists
        } elseif ( typeof arg === 'string' && typeof instance[arg] === 'function' ) {

            // copy arguments & remove function name
            args = Array.prototype.slice.call( arguments, 1 );

            // call the methodreturn instance[arg].apply( instance, args );

        } else {

            $.error('Method ' + arg + ' does not exist on jQuery.' + pluginName);

        }
    };

}(jQuery, window, document));

Notes:

  • This boilerplate will not use .each() for every method call, you should use .each() when you need
  • Allow re-init plugin, but only 1 instance will be created
  • Example of destroy method is included

Ref: https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/jQuery-boilerplate-and-demo

Solution 3:

Have you tried the jQuery UI Widget Factory?

There was a bit of a learning curve, but I love it now, handle the options, and defaults and allows methods, keeps everything wrapped up tight very fancy :)


EDIT

The jQuery UI Widget Factory is a separate component of the jQuery UI Library that provides an easy, object oriented way to create stateful jQuery plugins.

Introduction to Stateful Plugins and the Widget Factory.

I don't think the extra overhead is much to be worried about in most circumstances. These days I write in coffescript and everything is compiled, minified and gzipped, so a few extra lines here and there doesn't make much of a difference. My research in website speed seems to indicate that the number of HTTP requests is a big deal - indeed the former colleague that put me on this track worked for a browser based game and was all about speed speed speed.

Solution 4:

Here is the latest boilerplate https://github.com/techlab/jquery-plugin-boilerplate

Also you can use the create-jquery-plugin npm CLI utility. just run

npx create-jquery-plugin

Post a Comment for "A Template For A Jquery Plugin With Options And Accessible Methods?"