Как создать плагин jQuery с методами? - PullRequest
186 голосов
/ 13 июля 2009

Я пытаюсь написать плагин jQuery, который предоставит дополнительные функции / методы объекту, который его вызывает. Все учебные пособия, которые я читаю онлайн (просматривал последние 2 часа), включают, как правило, как добавлять опции, но не дополнительные функции.

Вот что я хочу сделать:

// форматировать div, чтобы он был контейнером сообщений, вызывая плагин для этого div

$("#mydiv").messagePlugin();
$("#mydiv").messagePlugin().saySomething("hello");

или что-то в этом роде. Вот что сводится к следующему: я вызываю плагин, затем вызываю функцию, связанную с этим плагином. Кажется, я не могу найти способ сделать это, и я видел много плагинов, делающих это раньше.

Вот что у меня есть для плагина:

jQuery.fn.messagePlugin = function() {
  return this.each(function(){
    alert(this);
  });

  //i tried to do this, but it does not seem to work
  jQuery.fn.messagePlugin.saySomething = function(message){
    $(this).html(message);
  }
};

Как мне достичь чего-то подобного?

Спасибо!


Обновление от 18 ноября 2013 г .: я изменил правильный ответ на следующие комментарии и комментарии Хари.

Ответы [ 20 ]

2 голосов
/ 07 апреля 2016

Здесь я хочу предложить шаги для создания простого плагина с аргументами.

JS

(function($) {
    $.fn.myFirstPlugin = function( options ) {

        // Default params
        var params = $.extend({
            text     : 'Default Title',
            fontsize : 10,
        }, options);
        return $(this).text(params.text);

    }
}(jQuery));

Здесь мы добавили объект по умолчанию params и установили значения параметров по умолчанию с помощью функции extend. Следовательно, если мы передадим пустой аргумент, он установит значения по умолчанию, в противном случае он установит.

HTML

$('.cls-title').myFirstPlugin({ text : 'Argument Title' });

Подробнее: Как создать плагин JQuery

1 голос
/ 02 августа 2014

Вот моя голая версия этого. Подобно тем, которые были опубликованы ранее, вы бы назвали:

$('#myDiv').MessagePlugin({ yourSettings: 'here' })
           .MessagePlugin('saySomething','Hello World!');

-или прямой доступ к экземпляру @ plugin_MessagePlugin

$elem = $('#myDiv').MessagePlugin();
var instance = $elem.data('plugin_MessagePlugin');
instance.saySomething('Hello World!');

MessagePlugin.js

;(function($){

    function MessagePlugin(element,settings){ // The Plugin
        this.$elem = element;
        this._settings = settings;
        this.settings = $.extend(this._default,settings);
    }

    MessagePlugin.prototype = { // The Plugin prototype
        _default: {
            message: 'Generic message'
        },
        initialize: function(){},
        saySomething: function(message){
            message = message || this._default.message;
            return this.$elem.html(message);
        }
    };

    $.fn.MessagePlugin = function(settings){ // The Plugin call

        var instance = this.data('plugin_MessagePlugin'); // Get instance

        if(instance===undefined){ // Do instantiate if undefined
            settings = settings || {};
            this.data('plugin_MessagePlugin',new MessagePlugin(this,settings));
            return this;
        }

        if($.isFunction(MessagePlugin.prototype[settings])){ // Call method if argument is name of method
            var args = Array.prototype.slice.call(arguments); // Get the arguments as Array
            args.shift(); // Remove first argument (name of method)
            return MessagePlugin.prototype[settings].apply(instance, args); // Call the method
        }

        // Do error handling

        return this;
    }

})(jQuery);
1 голос
/ 30 июня 2014

Попробуйте это:

$.fn.extend({
"calendar":function(){
    console.log(this);
    var methods = {
            "add":function(){console.log("add"); return this;},
            "init":function(){console.log("init"); return this;},
            "sample":function(){console.log("sample"); return this;}
    };

    methods.init(); // you can call any method inside
    return methods;
}}); 
$.fn.calendar() // caller or 
$.fn.calendar().sample().add().sample() ......; // call methods
0 голосов
/ 20 июля 2012

То, что вы сделали, - это расширение jQuery.fn.messagePlugin объекта новым методом. Что полезно, но не в вашем случае.

Вы должны использовать эту технику

function methodA(args){ this // refers to object... }
function saySomething(message){ this.html(message);  to first function }

jQuery.fn.messagePlugin = function(opts) {
  if(opts=='methodA') methodA.call(this);
  if(opts=='saySomething') saySomething.call(this, arguments[0]); // arguments is an array of passed parameters
  return this.each(function(){
    alert(this);
  });

};

Но вы можете выполнить то, что хотите, я имею в виду, что есть способ сделать $ ("# mydiv"). MessagePlugin (). SaySomething ("hello"); Мой друг, он начал писать о lugins и о том, как расширить их с помощью своей функциональности, вот ссылка на его блог

0 голосов
/ 23 января 2018

Следующая структура плагина использует jQuery- data() -метод для предоставления открытого интерфейса для внутренних методов / настроек плагина (при сохранении jQuery-chainability):

(function($, window, undefined) {

  $.fn.myPlugin = function(options) {

    // settings, e.g.:  
    var settings = $.extend({
      elementId: null,
      shape: "square",
      color: "aqua",
      borderWidth: "10px",
      borderColor: "DarkGray"
    }, options);

    // private methods, e.g.:
    var setBorder = function(color, width) {        
      settings.borderColor = color;
      settings.borderWidth = width;          
      drawShape();
    };

    var drawShape = function() {         
      $('#' + settings.elementId).attr('class', settings.shape + " " + "center"); 
      $('#' + settings.elementId).css({
        'background-color': settings.color,
        'border': settings.borderWidth + ' solid ' + settings.borderColor      
      });
      $('#' + settings.elementId).html(settings.color + " " + settings.shape);            
    };

    return this.each(function() { // jQuery chainability     
      // set stuff on ini, e.g.:
      settings.elementId = $(this).attr('id'); 
      drawShape();

      // PUBLIC INTERFACE 
      // gives us stuff like: 
      //
      //    $("#...").data('myPlugin').myPublicPluginMethod();
      //
      var myPlugin = {
        element: $(this),
        // access private plugin methods, e.g.: 
        setBorder: function(color, width) {        
          setBorder(color, width);
          return this.element; // To ensure jQuery chainability 
        },
        // access plugin settings, e.g.: 
        color: function() {
          return settings.color;
        },        
        // access setting "shape" 
        shape: function() {
          return settings.shape;
        },     
        // inspect settings 
        inspectSettings: function() {
          msg = "inspecting settings for element '" + settings.elementId + "':";   
          msg += "\n--- shape: '" + settings.shape + "'";
          msg += "\n--- color: '" + settings.color + "'";
          msg += "\n--- border: '" + settings.borderWidth + ' solid ' + settings.borderColor + "'";
          return msg;
        },               
        // do stuff on element, e.g.:  
        change: function(shape, color) {        
          settings.shape = shape;
          settings.color = color;
          drawShape();   
          return this.element; // To ensure jQuery chainability 
        }
      };
      $(this).data("myPlugin", myPlugin);
    }); // return this.each 
  }; // myPlugin
}(jQuery));

Теперь вы можете вызывать внутренние методы плагина для доступа или изменения данных плагина или соответствующего элемента, используя следующий синтаксис:

$("#...").data('myPlugin').myPublicPluginMethod(); 

Пока вы возвращаете текущий элемент (this) из вашей реализации myPublicPluginMethod() jQuery-chainability будут сохранены - так работают следующие:

$("#...").data('myPlugin').myPublicPluginMethod().css("color", "red").html("...."); 

Вот несколько примеров (для подробностей ознакомьтесь с этим fiddle ):

// initialize plugin on elements, e.g.:
$("#shape1").myPlugin({shape: 'square', color: 'blue', borderColor: 'SteelBlue'});
$("#shape2").myPlugin({shape: 'rectangle', color: 'red', borderColor: '#ff4d4d'});
$("#shape3").myPlugin({shape: 'circle', color: 'green', borderColor: 'LimeGreen'});

// calling plugin methods to read element specific plugin settings:
console.log($("#shape1").data('myPlugin').inspectSettings());    
console.log($("#shape2").data('myPlugin').inspectSettings());    
console.log($("#shape3").data('myPlugin').inspectSettings());      

// calling plugin methods to modify elements, e.g.:
// (OMG! And they are chainable too!) 
$("#shape1").data('myPlugin').change("circle", "green").fadeOut(2000).fadeIn(2000);      
$("#shape1").data('myPlugin').setBorder('LimeGreen', '30px');

$("#shape2").data('myPlugin').change("rectangle", "red"); 
$("#shape2").data('myPlugin').setBorder('#ff4d4d', '40px').css({
  'width': '350px',
  'font-size': '2em' 
}).slideUp(2000).slideDown(2000);              

$("#shape3").data('myPlugin').change("square", "blue").fadeOut(2000).fadeIn(2000);   
$("#shape3").data('myPlugin').setBorder('SteelBlue', '30px');

// etc. ...     
0 голосов
/ 05 сентября 2014

На самом деле это можно сделать так, чтобы работать «хорошо», используя defineProperty. Где «хороший» означает отсутствие необходимости использовать () для получения пространства имен плагина или передачи имени функции через строку.

Нит совместимости: defineProperty не работает в древних браузерах, таких как IE8 и ниже. Предупреждение: $.fn.color.blue.apply(foo, args) не сработает, вам нужно использовать foo.color.blue.apply(foo, args).

function $_color(color)
{
    return this.css('color', color);
}

function $_color_blue()
{
    return this.css('color', 'blue');
}

Object.defineProperty($.fn, 'color',
{
    enumerable: true,
    get: function()
    {
        var self = this;

        var ret = function() { return $_color.apply(self, arguments); }
        ret.blue = function() { return $_color_blue.apply(self, arguments); }

        return ret;
    }
});

$('#foo').color('#f00');
$('#bar').color.blue();

JSFiddle link

0 голосов
/ 25 февраля 2016

Вот как я это делаю:

(function ( $ ) {

$.fn.gridview = function( options ) {

    ..........
    ..........


    var factory = new htmlFactory();
    factory.header(...);

    ........

};

}( jQuery ));


var htmlFactory = function(){

    //header
     this.header = function(object){
       console.log(object);
  }
 }
0 голосов
/ 16 февраля 2016

Ниже приведен небольшой плагин, в котором есть метод предупреждения для целей отладки. Сохраните этот код в файле jquery.debug.js: JS:

jQuery.fn.warning = function() {
   return this.each(function() {
      alert('Tag Name:"' + $(this).prop("tagName") + '".');
   });
};

HTML:

<html>
   <head>
      <title>The jQuery Example</title>

      <script type = "text/javascript" 
         src = "http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

      <script src = "jquery.debug.js" type = "text/javascript"></script>

      <script type = "text/javascript" language = "javascript">
         $(document).ready(function() {
            $("div").warning();
            $("p").warning();
         });
      </script> 
   </head>

   <body>
      <p>This is paragraph</p>
      <div>This is division</div>
   </body>

</html>
0 голосов
/ 08 апреля 2015

Я думаю, что это может помочь вам ...

(function ( $ ) {
  
    $.fn.highlight = function( options ) {
  
        // This is the easiest way to have default options.
        var settings = $.extend({
            // These are the defaults.
            color: "#000",
            backgroundColor: "yellow"
        }, options );
  
        // Highlight the collection based on the settings variable.
        return this.css({
            color: settings.color,
            backgroundColor: settings.backgroundColor
        });
  
    };
  
}( jQuery ));

В приведенном выше примере я создал простой плагин jquery highlight . Я поделился статьей, в которой обсуждал Как создать свой собственный плагин jQuery от Basic до Advance , Я думаю, тебе стоит это проверить ... http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/

0 голосов
/ 27 марта 2015

В соответствии со стандартом jquery вы можете создать плагин следующим образом:

(function($) {

    //methods starts here....
    var methods = {
        init : function(method,options) {
             this.loadKeywords.settings = $.extend({}, this.loadKeywords.defaults, options);
             methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
             $loadkeywordbase=$(this);
        },
        show : function() {
            //your code here.................
        },
        getData : function() {
           //your code here.................
        }

    } // do not put semi colon here otherwise it will not work in ie7
    //end of methods

    //main plugin function starts here...
    $.fn.loadKeywords = function(options,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 ecw-Keywords');
        }
    };
    $.fn.loadKeywords.defaults = {
            keyName:     'Messages',
            Options:     '1',
            callback: '',
    };
    $.fn.loadKeywords.settings = {};
    //end of plugin keyword function.

})(jQuery);

Как вызвать этот плагин?

1.$('your element').loadKeywords('show',{'callback':callbackdata,'keyName':'myKey'}); // show() will be called

Ссылка: ссылка

...