Ich möchte ein Plugin mit zugänglichen Methoden und Optionen erstellen, dies für ein komplexes Plugin. Ich brauche die Methoden, um außerhalb des Plugins zugänglich zu sein, denn wenn jemand etwas im DOM anzeigt, muss es aktualisiert werden (damit wir das komplette Plugin nicht erneut ausführen müssen).

Ich habe in der Vergangenheit gesehen, dass es Plugins gibt, die das so machen, aber ich kann sie nicht finden, also kann ich sie mir nicht ansehen. Ich bin noch neu in Javascript, daher wäre jede Hilfe nett.

Es wäre schön, wenn wir die Optionen immer noch global überschreiben könnten.

Wie ich das Plugin verwenden möchte:

// options
$('#someid').myplugin({name: 'hello world'});

// methods(would be nice if we can use this)
$('#someid').myplugin('update');

// mein alter Plugin Wrapper

;(function($, window, document, undefined){

    $.fn.pluginmyPlugin = function(options) { 

        options = $.extend({}, $.fn.pluginmyPlugin.options, options); 

            return this.each(function() {  

                var obj = $(this);

                // the code 
            });     
        };

        /**
        * Default settings(dont change).
        * You can globally override these options
        * by using $.fn.pluginName.key = 'value';
        **/
        $.fn.pluginmyPlugin.options = {
            name: '',
                            ...         
        };

})(jQuery, window, document);

Aktualisieren

Nachdem ich mir die jQuery-Dokumente angesehen habe, die ich erstellt habe, lassen Sie mich bitte wissen, ob etwas mit dem Code nicht stimmt, ob er besser erstellt werden kann ...

;(function($, window, document, undefined){

    var methods = {

        init : function( options ) {

            options = $.extend({}, $.fn.pluginmyPlugin.options, options); 

            return this.each(function(){

            alert('yes i am the main code')

            });
        },
        update : function( ) {
             alert('updated')
        }
    };

    $.fn.pluginmyPlugin = function(method) { 

        if ( methods[method] ) {
          return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply( this, arguments );
        } else {
          $.error( 'Method ' +  method + ' does not exist on this plugin' );
        }    

    };

        /**
        * Default settings(dont change).
        * You can globally override these options
        * by using $.fn.pluginName.key = 'value';
        **/
        $.fn.pluginmyPlugin.options = {
            name: 'john doe',
            //....
        };

})(jQuery, window, document);
5
user759235 8 Dez. 2012 im 16:53

3 Antworten

Beste Antwort

Eine Alternative:

var Plugin = 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;

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

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

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

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

Verwendung:

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

Dies ähnelt absurd der JavaScript-Vorlage von Twitter Bootstrap. Aber es dauerte nicht ganz von dort. Ich habe eine lange Tradition in der Verwendung von .data().

Vergessen Sie nicht, es angemessen zu verpacken.

3
Alexander 2 Jän. 2013 im 20:21

Haben Sie die jQuery UI Widget Factory ausprobiert?

Es gab eine gewisse Lernkurve, aber ich liebe es jetzt, handhabe die Optionen und die Standardeinstellungen und erlaube Methoden, halte alles eng zusammen, sehr ausgefallen :)


BEARBEITEN

Die jQuery UI Widget Factory ist eine separate Komponente der jQuery UI Library, die eine einfache, objektorientierte Möglichkeit zum Erstellen statusbehafteter jQuery-Plugins bietet.

- Einführung in Stateful Plugins und die Widget Factory.

Ich denke nicht, dass der zusätzliche Aufwand in den meisten Fällen viel zu befürchten ist. Heutzutage schreibe ich in Coffescript und alles wird kompiliert, minimiert und gezippt, so dass ein paar zusätzliche Zeilen hier und da keinen großen Unterschied machen. Meine Untersuchungen zur Geschwindigkeit von Websites scheinen darauf hinzudeuten, dass die Anzahl der HTTP-Anfragen eine große Sache ist - tatsächlich arbeitete der ehemalige Kollege, der mich auf diesen Track gebracht hat, für ein browserbasiertes Spiel und drehte sich alles um Geschwindigkeit, Geschwindigkeit.

1
CodeMonkey 7 Jän. 2013 im 13:55

Wenn Sie das Plugin wie folgt verwenden möchten:

// 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') );
    });

Oder wenn Sie eine unabhängige Plugin-Instanz pro Element benötigen:

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

Sie möchten Ihr Plugin folgendermaßen einrichten:

/*
 *  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"
        };

    function privateMethod () {
        console.log("private method");
    }

    // The actual plugin constructor
    function Plugin() {
        /*
         * 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 instance
            this.element.data( dataPlugin, null );
        },

        // public get method
        href: function () {
            return this.element.attr( 'href' );
        },

        // public chaining method
        changeBG: function ( color = null ) {
            color = color || this.options['color'];
            return this.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 once
        if (!( this.data( dataPlugin ) instanceof Plugin )) {

            // if no instance, create one
            this.data( dataPlugin, new Plugin( 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
        } else if ( typeof arg === 'string' && typeof instance[arg] === 'function' ) {

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

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

        } else {

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

        }
    };

}(jQuery, window, document));

Hinweise:

  • Dieses Boilerplate verwendet nicht .each () für jeden Methodenaufruf. Sie sollten .each () bei Bedarf verwenden
  • Erlaube das Re-Init-Plugin, aber es wird nur 1 Instanz erstellt
  • Ein Beispiel für eine Zerstörungsmethode ist enthalten

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

2
peater 4 März 2020 im 01:41