简体   繁体   English

如何使用插件方法创建Jquery插件并保持可链接性?

[英]How to create a Jquery Plugin with Plugin Methods and Maintaining Chainability?

I am trying to create a Jquery plugin that maintains chainability and has public methods as specified in Jquery Plugins/Authoring . 我正在尝试创建一个Jquery插件,该插件可保持可链接性并具有Jquery Plugins / Authoring中指定的公共方法。 The complexity is that it is trying to maintain certain vars that I want the public methods to use. 复杂性在于它试图维护某些我希望公共方法使用的变量。

This is my jsfiddle : http://jsfiddle.net/badmash69/9cqcj/2/ 这是我的jsfiddle: http : //jsfiddle.net/badmash69/9cqcj/2/

javascript code :

(function($){

  var methods = {
    init : function( options ) {
      this.options = options;
    }
  , add_that: function (elem) {

      $(this).append(elem);
      return (this);
    }
  , show_parent: function(){
      // this is a simple test to see if the plugin vars are accessible
      alert("parent id=" + $(this).parentId)
    }              
  , add_this: function (elem) {
      return methods.add_that.apply(this,elem);
    }
  };

  $.fn.test = function (method) { 
        var args = method;
        var argss = Array.prototype.slice.call(args, 1);      


      return this.each(function(){

          var $this = $(this);
          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 jQuery.test' );
    }          


          var element = $(this);
          var parentId= element.parent().attr("id")

      });       


  };

})(jQuery);

$('#test').test('add_this',$('<div>Hello World d</div>'));

$('#test').test('show_parent');
​

Html Code HTML代码

<div id="holder">
<div id="test"></div>
</div>  

I cant figure out what I am doping wrong here . 我不能弄清楚我在这里用错了什么。 How can I make it work ? 我该如何运作? I would deeply appreciate any help . 我将不胜感激。

the way that I do this is using the $.data, you can have specific object local vars, "public"/"private" methods, etc. here goes an small example in how I will do it 我使用$ .data的方式,可以有特定的对象本地var,“ public” /“ private”方法等。这是我将如何做的一个小例子

(function($){
      var myTestMethods = function() {
          // local variables
          var last_added;

          // local "private" methods 
          var init=function(options) {
              this.options = options;
              last_added = null;
              return this;
          };

          var add_that=function(elem) {
              last_added = elem;
              this.append(elem);
              return this;
          };

          var show_parent=function() {
              alert("parent id=" + this.parent().attr('id'));
          }

          return { // this are your obj "public" methods
                 // notice we are not listing add_that method, therefore this method will be a "private" method
            init : init,
            show_parent: show_parent, // you can publish a private method
            get_last_added: function(){
              return last_added; // you can access local variables
            }, 
            add_this: function (elem) {
              return add_that.apply(this, elem);  // you can also run local methods
            }
          }
      };

      $.fn.test = function (method) {
          var obj_data = this.data('myTestData');
        if (typeof(obj_data) != "undefined") {
          if ( obj_data[method] ) {
            return obj_data[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
          }else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.test' );
          }
        } else {
          if (typeof(method) === 'object' || ! method) {
            obj_data = myTestMethods();
            this.data('myTestData', obj_data);
            return obj_data.init.apply(this, arguments);
          }
        }
      };

    })(jQuery);

    $('#test').test(); //init

    $('#test').test('add_this',$('<div>Hello World d</div>'));
    $('#test').test('show_parent');

this code has small tests so there may be small bugs, but this will show you the basic idea in how to do what you want. 这段代码经过了小的测试,因此可能会有小的bug,但这将向您展示如何做所需的基本思想。

Take a look at this demo: http://jsfiddle.net/9cqcj/11/ 看一下这个演示: http : //jsfiddle.net/9cqcj/11/

As they suggest, to keep data you should better use .data : 正如他们建议的那样,要保留数据,您最好使用.data

      return this.each(function(){          
          var $this = $(this);
          $this.data("parentId",$this.parent().attr("id"));
....

(assuming that you need parentId of each element in set) (假设您需要set中每个元素的parentId)

Also, you have a problem with calling your methods: 另外,您在调用方法时遇到问题:

 return this.each(function(){

          var $this = $(this);
          if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));

Last line, arguments - arguments of function passed to .each is used. 最后一行, arguments使用传递给.each的函数参数。 In order to get original arguments save them into variable before calling a method: 为了获取原始参数,请在调用方法之前将其保存到变量中:

$.fn.test = function (method) { 
        var args = arguments;      
      return this.each(function(){          
          var $this = $(this);
          $this.data("parentId",$this.parent().attr("id"));
          if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( args , 1 ));

See arguments replaced with args in last line. 请参阅最后一行用args替换的参数。

Also, when you are using .apply , second parameter should be an array: 另外,当您使用.apply ,第二个参数应该是一个数组:

return methods.add_that.apply(this, [elem]);

In case like this: 在这种情况下:

return methods.add_that.apply(this, elem);

You can get unexpected problems. 您会遇到意想不到的问题。 For instance, try to replace elem with simple string "test" and see what you will get in console. 例如,尝试将elem替换为简单的字符串"test"然后看看您将在控制台中得到什么。 Or if you will pass jQuery object, you will get DOM object in called method 或者,如果您将传递jQuery对象,则将在被调用的方法中获得DOM对象。

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

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