简体   繁体   English

如何使用方法创建 jQuery 插件?

[英]How to create a jQuery plugin with methods?

I'm trying to write a jQuery plugin that will provide additional functions/methods to the object that calls it.我正在尝试编写一个 jQuery 插件,它将为调用它的对象提供额外的功能/方法。 All the tutorials I read online (have been browsing for the past 2 hours) include, at the most, how to add options, but not additional functions.我在网上看的所有教程(过去2小时一直在浏览)最多包括如何添加选项,而不是附加功能。

Here's what I am looking to do:这是我想要做的:

//format div to be a message container by calling the plugin for that div //通过调用该div的插件将div格式化为消息容器

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

or something along those lines.或类似的规定。 Here's what it boils down to: I call the plugin, then I call a function associated with that plugin.归结为:我调用插件,然后调用与该插件关联的函数。 I can't seem to find a way to do this, and I've seen many plugins do it before.我似乎找不到办法做到这一点,而且我以前见过很多插件都这样做。

Here's what I have so far for the plugin:到目前为止,这是我对插件的了解:

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

How can I achieve something like that?我怎样才能实现这样的目标?

Thank you!谢谢!


Update Nov 18, 2013: I've changed the correct answer to that of Hari's following comments and upvotes. 2013 年 11 月 18 日更新:我已经更改了 Hari 以下评论和赞成票的正确答案。

According to the jQuery Plugin Authoring page ( http://docs.jquery.com/Plugins/Authoring ), it's best not to muddy up the jQuery and jQuery.fn namespaces.根据 jQuery 插件创作页面 ( http://docs.jquery.com/Plugins/Authoring ),最好不要混淆 jQuery 和 jQuery.fn 命名空间。 They suggest this method:他们建议这种方法:

(function( $ ){

    var methods = {
        init : function(options) {

        },
        show : function( ) {    },// IS
        hide : function( ) {  },// GOOD
        update : function( content ) {  }// !!!
    };

    $.fn.tooltip = function(methodOrOptions) {
        if ( methods[methodOrOptions] ) {
            return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
            // Default to "init"
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.tooltip' );
        }    
    };


})( jQuery );

Basically you store your functions in an array (scoped to the wrapping function) and check for an entry if the parameter passed is a string, reverting to a default method ("init" here) if the parameter is an object (or null).基本上,您将函数存储在一个数组中(作用域为包装函数),如果传递的参数是一个字符串,则检查一个条目,如果参数是一个对象(或 null),则恢复为默认方法(此处为“init”)。

Then you can call the methods like so...然后你可以像这样调用方法......

$('div').tooltip(); // calls the init method
$('div').tooltip({  // calls the init method
  foo : 'bar'
});
$('div').tooltip('hide'); // calls the hide method
$('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method

Javascripts "arguments" variable is an array of all the arguments passed so it works with arbitrary lengths of function parameters. Javascripts“arguments”变量是传递的所有参数的数组,因此它适用于任意长度的函数参数。

Here's the pattern I have used for creating plugins with additional methods.这是我用来创建带有附加方法的插件的模式。 You would use it like:你会像这样使用它:

$('selector').myplugin( { key: 'value' } );

or, to invoke a method directly,或者,直接调用一个方法,

$('selector').myplugin( 'mymethod1', 'argument' );

Example:例子:

;(function($) {

    $.fn.extend({
        myplugin: function(options,arg) {
            if (options && typeof(options) == 'object') {
                options = $.extend( {}, $.myplugin.defaults, options );
            }

            // this creates a plugin for each element in
            // the selector or runs the function once per
            // selector.  To have it do so for just the
            // first element (once), return false after
            // creating the plugin to stop the each iteration 
            this.each(function() {
                new $.myplugin(this, options, arg );
            });
            return;
        }
    });

    $.myplugin = function( elem, options, arg ) {

        if (options && typeof(options) == 'string') {
           if (options == 'mymethod1') {
               myplugin_method1( arg );
           }
           else if (options == 'mymethod2') {
               myplugin_method2( arg );
           }
           return;
        }

        ...normal plugin actions...

        function myplugin_method1(arg)
        {
            ...do method1 with this and arg
        }

        function myplugin_method2(arg)
        {
            ...do method2 with this and arg
        }

    };

    $.myplugin.defaults = {
       ...
    };

})(jQuery);

What about this approach:这种方法怎么样:

jQuery.fn.messagePlugin = function(){
    var selectedObjects = this;
    return {
             saySomething : function(message){
                              $(selectedObjects).each(function(){
                                $(this).html(message);
                              });
                              return selectedObjects; // Preserve the jQuery chainability 
                            },
             anotherAction : function(){
                               //...
                               return selectedObjects;
                             }
           };
}
// Usage:
$('p').messagePlugin().saySomething('I am a Paragraph').css('color', 'red');

The selected objects are stored in the messagePlugin closure, and that function returns an object that contains the functions associated with the plugin, the in each function you can perform the desired actions to the currently selected objects.选定的对象存储在 messagePlugin 闭包中,该函数返回一个包含与插件关联的函数的对象,在每个函数中,您可以对当前选定的对象执行所需的操作。

You can test and play with the code here .您可以在此处测试和使用代码。

Edit: Updated code to preserve the power of the jQuery chainability.编辑:更新代码以保留 jQuery 链接能力的强大功能。

The problem with the currently selected answer is that you're not actually creating a new instance of the custom plugin for every element in the selector like you think you're doing... you're actually only creating a single instance and passing in the selector itself as the scope.当前选择的答案的问题是你实际上并没有像你认为的那样为选择器中的每个元素创建自定义插件的新实例......你实际上只是创建一个实例并传入选择器本身作为范围。

View this fiddle for a deeper explanation.查看此小提琴以获得更深入的解释。

Instead, you'll need to loop through the selector using jQuery.each and instantiate a new instance of the custom plugin for every element in the selector.相反,您需要使用jQuery.each遍历选择器并为选择器中的每个元素实例化自定义插件的新实例。

Here's how:这是如何做:

(function($) {

    var CustomPlugin = function($el, options) {

        this._defaults = {
            randomizer: Math.random()
        };

        this._options = $.extend(true, {}, this._defaults, options);

        this.options = function(options) {
            return (options) ?
                $.extend(true, this._options, options) :
                this._options;
        };

        this.move = function() {
            $el.css('margin-left', this._options.randomizer * 100);
        };

    };

    $.fn.customPlugin = function(methodOrOptions) {

        var method = (typeof methodOrOptions === 'string') ? methodOrOptions : undefined;

        if (method) {
            var customPlugins = [];

            function getCustomPlugin() {
                var $el          = $(this);
                var customPlugin = $el.data('customPlugin');

                customPlugins.push(customPlugin);
            }

            this.each(getCustomPlugin);

            var args    = (arguments.length > 1) ? Array.prototype.slice.call(arguments, 1) : undefined;
            var results = [];

            function applyMethod(index) {
                var customPlugin = customPlugins[index];

                if (!customPlugin) {
                    console.warn('$.customPlugin not instantiated yet');
                    console.info(this);
                    results.push(undefined);
                    return;
                }

                if (typeof customPlugin[method] === 'function') {
                    var result = customPlugin[method].apply(customPlugin, args);
                    results.push(result);
                } else {
                    console.warn('Method \'' + method + '\' not defined in $.customPlugin');
                }
            }

            this.each(applyMethod);

            return (results.length > 1) ? results : results[0];
        } else {
            var options = (typeof methodOrOptions === 'object') ? methodOrOptions : undefined;

            function init() {
                var $el          = $(this);
                var customPlugin = new CustomPlugin($el, options);

                $el.data('customPlugin', customPlugin);
            }

            return this.each(init);
        }

    };

})(jQuery);

And a working fiddle .和一个工作小提琴

You'll notice how in the first fiddle, all divs are always moved to the right the exact same number of pixels.您会注意到在第一个小提琴中,所有 div 总是向右移动完全相同的像素数。 That is because only one options object exists for all elements in the selector.这是因为选择器中的所有元素都只存在一个选项对象。

Using the technique written above, you'll notice that in the second fiddle, each div is not aligned and is randomly moved (excluding the first div as it's randomizer is always set to 1 on line 89).使用上面写的技术,您会注意到在第二个小提琴中,每个 div 都没有对齐并且随机移动(第一个 div 除外,因为它的随机发生器在第 89 行始终设置为 1)。 That is because we are now properly instantiating a new custom plugin instance for every element in the selector.那是因为我们现在正确地为选择器中的每个元素实例化了一个新的自定义插件实例。 Every element has its own options object and is not saved in the selector, but in the instance of the custom plugin itself.每个元素都有自己的选项对象,并且不保存在选择器中,而是保存在自定义插件本身的实例中。

This means that you'll be able to access the methods of the custom plugin instantiated on a specific element in the DOM from new jQuery selectors and aren't forced to cache them, as you would be in the first fiddle.这意味着您将能够从新的 jQuery 选择器访问在 DOM 中的特定元素上实例化的自定义插件的方法,并且不会像您在第一个小提琴中那样被迫缓存它们。

For example, this would return an array of all options objects using the technique in the second fiddle.例如,这将使用第二个小提琴中的技术返回所有选项对象的数组。 It would return undefined in the first.它首先会返回 undefined 。

$('div').customPlugin();
$('div').customPlugin('options'); // would return an array of all options objects

This is how you would have to access the options object in the first fiddle, and would only return a single object, not an array of them:这就是您必须访问第一个小提琴中的选项对象的方式,并且只会返回一个对象,而不是它们的数组:

var divs = $('div').customPlugin();
divs.customPlugin('options'); // would return a single options object

$('div').customPlugin('options');
// would return undefined, since it's not a cached selector

I'd suggest using the technique above, not the one from the currently selected answer.我建议使用上面的技术,而不是当前选择的答案中的技术。

Use the jQuery UI Widget Factory .使用jQuery UI 小部件工厂

Example:例子:

$.widget( "myNamespace.myPlugin", {

    options: {
        // Default options
    },
 
    _create: function() {
        // Initialization logic here
    },
 
    // Create a public method.
    myPublicMethod: function( argument ) {
        // ...
    },

    // Create a private method.
    _myPrivateMethod: function( argument ) {
        // ...
    }
 
});

Initialization:初始化:

$('#my-element').myPlugin();
$('#my-element').myPlugin( {defaultValue:10} );

Method calling:方法调用:

$('#my-element').myPlugin('myPublicMethod', 20);

(This is how the jQuery UI library is built.) (这就是jQuery UI库的构建方式。)

A simpler approach is to use nested functions.一种更简单的方法是使用嵌套函数。 Then you can chain them in an object-oriented fashion.然后您可以以面向对象的方式链接它们。 Example:例子:

jQuery.fn.MyPlugin = function()
{
  var _this = this;
  var a = 1;

  jQuery.fn.MyPlugin.DoSomething = function()
  {
    var b = a;
    var c = 2;

    jQuery.fn.MyPlugin.DoSomething.DoEvenMore = function()
    {
      var d = a;
      var e = c;
      var f = 3;
      return _this;
    };

    return _this;
  };

  return this;
};

And here's how to call it:下面是如何称呼它:

var pluginContainer = $("#divSomeContainer");
pluginContainer.MyPlugin();
pluginContainer.MyPlugin.DoSomething();
pluginContainer.MyPlugin.DoSomething.DoEvenMore();

Be careful though.不过要小心。 You cannot call a nested function until it has been created.在创建嵌套函数之前,您不能调用它。 So you cannot do this:所以你不能这样做:

var pluginContainer = $("#divSomeContainer");
pluginContainer.MyPlugin();
pluginContainer.MyPlugin.DoSomething.DoEvenMore();
pluginContainer.MyPlugin.DoSomething();

The DoEvenMore function doesn't even exist because the DoSomething function hasn't been run yet which is required to create the DoEvenMore function. DoEvenMore 函数甚至不存在,因为尚未运行创建 DoEvenMore 函数所需的 DoSomething 函数。 For most jQuery plugins, you really are only going to have one level of nested functions and not two as I've shown here.对于大多数 jQuery 插件,您实际上只会有一层嵌套函数,而不是我在这里展示的两层。
Just make sure that when you create nested functions that you define these functions at the beginning of their parent function before any other code in the parent function gets executed.只需确保在创建嵌套函数时,在执行父函数中的任何其他代码之前,在父函数的开头定义这些函数。

Finally, note that the "this" member is stored in a variable called "_this".最后,请注意“this”成员存储在名为“_this”的变量中。 For nested functions, you should return "_this" if you need a reference to the instance in the calling client.对于嵌套函数,如果需要在调用客户端中引用实例,则应返回“_this”。 You cannot just return "this" in the nested function because that will return a reference to the function and not the jQuery instance.您不能只在嵌套函数中返回“this”,因为那样会返回对函数的引用而不是 jQuery 实例。 Returning a jQuery reference allows you to chain intrinsic jQuery methods on return.返回 jQuery 引用允许您在返回时链接内部 jQuery 方法。

I got it from jQuery Plugin Boilerplate我从jQuery Plugin Boilerplate得到它

Also described in jQuery Plugin Boilerplate, reprisejQuery Plugin Boilerplate 中也有描述,reprise

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

// remember to change every instance of "pluginName" to the name of your plugin!
(function($) {

    // here we go!
    $.pluginName = function(element, options) {

    // plugin's default options
    // this is private property and is accessible only from inside the plugin
    var defaults = {

        foo: 'bar',

        // if your plugin is event-driven, you may provide callback capabilities
        // for its events. execute these functions before or after events of your
        // plugin, so that users may customize those particular events without
        // changing the plugin's code
        onFoo: function() {}

    }

    // to avoid confusions, use "plugin" to reference the
    // current instance of the object
    var plugin = this;

    // this will hold the merged default, and user-provided options
    // plugin's properties will be available through this object like:
    // plugin.settings.propertyName from inside the plugin or
    // element.data('pluginName').settings.propertyName from outside the plugin,
    // where "element" is the element the plugin is attached to;
    plugin.settings = {}

    var $element = $(element), // reference to the jQuery version of DOM element
    element = element; // reference to the actual DOM element

    // the "constructor" method that gets called when the object is created
    plugin.init = function() {

    // the plugin's final properties are the merged default and
    // user-provided options (if any)
    plugin.settings = $.extend({}, defaults, options);

    // code goes here

   }

   // public methods
   // these methods can be called like:
   // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
   // element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside
   // the plugin, where "element" is the element the plugin is attached to;

   // a public method. for demonstration purposes only - remove it!
   plugin.foo_public_method = function() {

   // code goes here

    }

     // private methods
     // these methods can be called only from inside the plugin like:
     // methodName(arg1, arg2, ... argn)

     // a private method. for demonstration purposes only - remove it!
     var foo_private_method = function() {

        // code goes here

     }

     // fire up the plugin!
     // call the "constructor" method
     plugin.init();

     }

     // add the plugin to the jQuery.fn object
     $.fn.pluginName = function(options) {

        // iterate through the DOM elements we are attaching the plugin to
        return this.each(function() {

          // if plugin has not already been attached to the element
          if (undefined == $(this).data('pluginName')) {

              // create a new instance of the plugin
              // pass the DOM element and the user-provided options as arguments
              var plugin = new $.pluginName(this, options);

              // in the jQuery version of the element
              // store a reference to the plugin object
              // you can later access the plugin and its methods and properties like
              // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
              // element.data('pluginName').settings.propertyName
              $(this).data('pluginName', plugin);

           }

        });

    }

})(jQuery);

Too late but maybe it can help someone one day.为时已晚,但也许有一天它可以帮助某人。

I was in the same situation like, creating a jQuery plugin with some methods, and after reading some articles and some tires I create a jQuery plugin boilerplate ( https://github.com/acanimal/jQuery-Plugin-Boilerplate ).我遇到了同样的情况,用一些方法创建了一个 jQuery 插件,在阅读了一些文章和一些轮胎之后,我创建了一个 jQuery 插件样板( https://github.com/acanimal/jQuery-Plugin-Boilerplate )。

In addition, I develop with it a plugin to manage tags ( https://github.com/acanimal/tagger.js ) and wrote a two blog posts explaining step by step the creation of a jQuery plugin ( https://www.acuriousanimal.com/blog/20130115/things-i-learned-creating-a-jquery-plugin-part-i ).此外,我用它开发了一个管理标签的插件( https://github.com/acanimal/tagger.js ),并写了两篇博客文章逐步解释了 jQuery 插件的创建( https://www. acuriousanimal.com/blog/20130115/things-i-learned-creating-a-jquery-plugin-part-i )。

You can do:你可以做:

(function($) {
  var YourPlugin = function(element, option) {
    var defaults = {
      //default value
    }

    this.option = $.extend({}, defaults, option);
    this.$element = $(element);
    this.init();
  }

  YourPlugin.prototype = {
    init: function() { },
    show: function() { },
    //another functions
  }

  $.fn.yourPlugin = function(option) {
    var arg = arguments,
        options = typeof option == 'object' && option;;
    return this.each(function() {
      var $this = $(this),
          data = $this.data('yourPlugin');

      if (!data) $this.data('yourPlugin', (data = new YourPlugin(this, options)));
      if (typeof option === 'string') {
        if (arg.length > 1) {
          data[option].apply(data, Array.prototype.slice.call(arg, 1));
        } else {
          data[option]();
        }
      }
    });
  };
});

In this way your plugins object is stored as data value in your element.通过这种方式,您的插件对象将作为数据值存储在您的元素中。

//Initialization without option
$('#myId').yourPlugin();

//Initialization with option
$('#myId').yourPlugin({
  // your option
});

// call show method
$('#myId').yourPlugin('show');

What about using triggers?使用触发器怎么样? Does anyone know any drawback using them?有谁知道使用它们有什么缺点吗? The benefit is that all internal variables are accessible via the triggers, and the code is very simple.好处是所有内部变量都可以通过触发器访问,而且代码非常简单。

See on jsfiddle .请参阅jsfiddle

Example usage用法示例

<div id="mydiv">This is the message container...</div>

<script>
    var mp = $("#mydiv").messagePlugin();

    // the plugin returns the element it is called on
    mp.trigger("messagePlugin.saySomething", "hello");

    // so defining the mp variable is not needed...
    $("#mydiv").trigger("messagePlugin.repeatLastMessage");
</script>

Plugin插入

jQuery.fn.messagePlugin = function() {

    return this.each(function() {

        var lastmessage,
            $this = $(this);

        $this.on('messagePlugin.saySomething', function(e, message) {
            lastmessage = message;
            saySomething(message);
        });

        $this.on('messagePlugin.repeatLastMessage', function(e) {
            repeatLastMessage();
        });

        function saySomething(message) {
            $this.html("<p>" + message + "</p>");
        }

        function repeatLastMessage() {
            $this.append('<p>Last message was: ' + lastmessage + '</p>');
        }

    });

}

Here I want to suggest steps to create simple plugin with arguments.在这里,我想建议创建带有参数的简单插件的步骤。

 (function($) { $.fn.myFirstPlugin = function(options) { // Default params var params = $.extend({ text: 'Default Title', fontsize: 10, }, options); return $(this).text(params.text); } }(jQuery)); $('.cls-title').myFirstPlugin({ text: 'Argument Title' });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h1 class="cls-title"></h1>

Here, we have added default object called params and set default values of options using extend function.在这里,我们添加了名为params的默认对象,并使用extend函数设置了选项的默认值。 Hence, If we pass blank argument then it will set default values instead otherwise it will set.因此,如果我们传递空白参数,那么它将设置默认值,否则它将设置。

Read more: How to Create JQuery plugin阅读更多:如何创建 JQuery 插件

Try this one:试试这个:

$.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

Here is my bare-bones version of this.这是我的基本版本。 Similar to the ones posted before, you would call like:与之前发布的类似,您可以这样调用:

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

-or access the instance directly @ plugin_MessagePlugin - 或者直接访问实例plugin_MessagePlugin

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

MessagePlugin.js 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);

The following plugin-structure utilizes the jQuery- data() -method to provide a public interface to internal plugin-methods/-settings (while preserving jQuery-chainability):以下插件结构利用 jQuery- data() -方法为内部插件方法/设置提供公共接口(同时保留 jQuery 链接能力):

(function($, window, undefined) { 
  const defaults = {
    elementId   : null,
    shape       : "square",
    color       : "aqua",
    borderWidth : "10px",
    borderColor : "DarkGray"
  };

  $.fn.myPlugin = function(options) {
    // settings, e.g.:  
    var settings = $.extend({}, defaults, 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));

Now you can call internal plugin-methods to access or modify plugin data or the relevant element using this syntax:现在您可以使用以下语法调用内部插件方法来访问或修改插件数据或相关元素:

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

As long as you return the current element (this) from inside your implementation of myPublicPluginMethod() jQuery-chainability will be preserved - so the following works:只要您从myPublicPluginMethod()的实现内部返回当前元素 (this),jQuery-chainability 就会被保留——因此以下工作:

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

Here are some examples (for details checkout this 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. ...     

This can actually be made to work in a "nice" way using defineProperty .这实际上可以使用defineProperty以“不错”的方式工作。 Where "nice" means without having to use () to get plugin namespace nor having to pass function name by string.其中“nice”意味着不必使用()来获取插件命名空间,也不必通过字符串传递函数名称。

Compatibility nit: defineProperty doesn't work in ancient browsers such as IE8 and below.兼容性 nit: defineProperty在 IE8 及以下版本的旧浏览器中不起作用。 Caveat: $.fn.color.blue.apply(foo, args) won't work, you need to use foo.color.blue.apply(foo, args) .警告: $.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 JSFiddle 链接

According to jquery standard you can create plugin as follow:根据 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);

How to call this plugin?怎么调用这个插件?

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

Reference: link参考:链接

I think this might help you...我想这可能对你有帮助......

 (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 ));

In the above example i had created a simple jquery highlight plugin.I had shared an article in which i had discussed about How to Create Your Own jQuery Plugin from Basic to Advance.在上面的示例中,我创建了一个简单的 jQuery突出显示插件。我分享了一篇文章,其中我讨论了如何创建自己的 jQuery 插件,从基础到高级。 I think you should check it out... http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/我认为您应该检查一下... http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/

Following is a small plug-in to have warning method for debugging purpose.下面是一个小插件,有调试目的的警告方法。 Keep this code in jquery.debug.js file: JS:将此代码保存在 jquery.debug.js 文件中:JS:

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

HTML: 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>

Here is how I do it:这是我的操作方法:

(function ( $ ) {

$.fn.gridview = function( options ) {

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


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

    ........

};

}( jQuery ));


var htmlFactory = function(){

    //header
     this.header = function(object){
       console.log(object);
  }
 }

What you did is basically extending jQuery.fn.messagePlugin object by new method.您所做的基本上是通过新方法扩展jQuery.fn.messagePlugin 对象 Which is useful but not in your case.这很有用,但对您而言不是。

You have to do is using this technique你所要做的就是使用这种技术

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

};

But you can accomplish what you want I mean there is a way to do $("#mydiv").messagePlugin().saySomething("hello");但是你可以完成你想要的我的意思是有一种方法可以做到 $("#mydiv").messagePlugin().saySomething("hello"); My friend he started writing about lugins and how to extend them with your chainf of functionalities here is the link to his blog我的朋友,他开始写有关 lugin 的文章以及如何使用您的功能链扩展它们,这里是他博客的链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM