使用配置设置创建jQuery插件

时间:2015-05-15 18:03:12

标签: javascript jquery jquery-plugins

我一直在使用以下设计模式来创建jQuery插件。我很确定我从jQuery主页获得了这个概念,但它似乎不再在那里发布了。

我最近尝试访问除settings方法之外的方法(即someOtherMethod ())中的init()变量,并且由于未定义settings而遇到错误。我看到原因settingsinit()方法隔离。

如果我将settings移到此方法之外,我可以从不同的方法访问它,但是,应用插件时的每个实例都不会有其唯一的设置变量,这是不可接受的。例如,$('#id1, #id2').myPlugin({x:111});应该有一个共同的settings变量,但$('#id1').myPlugin({x:111}); $('#id2').myPlugin({x:222});每个都应该有唯一的设置变量。

考虑到以下设计模式作为起点,如何从与插件关联的所有方法访问settings变量,但每次应用插件时都有一个唯一的settings变量? / p>

(function( $ ){

    var defaults={
        x : 123,
        y : 321
    };
    // var settings={}; //Should settings be defined here???

    var methods = {
        init : function( options ) {
            var settings = $.extend(defaults, options  || {});
            //settings = $.extend(defaults, options  || {}); //Should settings just be updated and not defined here?
            return this.each(function(){
                //whatever
            });
        },

        someOtherMethod : function() {
            return $(this).each(function(){
                //do whatever and use settings variable as applicable
            })
        },
    };

    $.fn.myPlugin = 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 jQuery.myPlugin' );
        }    
    };

}( jQuery ));

$('#id1, #id2').myPlugin({x:111});  //Sets x=111 in settings for both
$('#id3').myPlugin({x:333});        //Sets x=333 in settings.
$('#id3').myPlugin('someOtherMethod');  //Will have access to x=333 in settings.

3 个答案:

答案 0 :(得分:4)

您希望每个元素保存设置对象,以便设置将在不同的选择器中保留。执行此操作的最佳方法是使用jQuery.data将设置对象附加到元素。这样,无论选择何种方式,每次选择元素时设置都将保持不变。

然后,在.each的{​​{1}}调用中,您可以使用元素someOtherMethod访问此数据。

此外,每个单独的元素都需要一个单独的设置对象,以避免覆盖共享设置,所以:

jQuery.data

将需要替换为:

var settings = $.extend(defaults, options  || {});

否则每次使用新设置属性覆盖var settings = $.extend({}, defaults, options || {}); 对象,并在所有元素之间共享。

在此示例中,我创建了一个变量名defaults,其值为internalPrefix,用于使用'_myPlugin'保存数据的密钥。我在底部添加了一些测试,以显示如何以不同的方式初始化它,但是可以调用该方法,并且仍然知道用于初始化元素的设置。

工作示例:



jQuery.data

(function( $ ){

    var defaults={
        x : 123,
        y : 321
    };
    //A variable to save the setting data under.
    var internalPrefix = '_myPlugin';

    var methods = {
        init : function( options ) {
            return this.each(function() {
                //Setup the settings object.
                var settings = $.extend({}, defaults, options || {});
                //Save the settings to the element.
                $(this).data(internalPrefix, settings);
            });
        },

        someOtherMethod : function() {
            return this.each(function() {
                //Get the existing settings.
                var settings = $(this).data(internalPrefix);
                //Example:
                $('<code></code>').text(JSON.stringify(settings)).appendTo(this);
            })
        },
    };

    $.fn.myPlugin = 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 jQuery.myPlugin' );
        }
    };

}( jQuery ));

//Initialize the plugin different ways.
$('.group-1').myPlugin();
$('.group-2').myPlugin({
    x : 42,
    y : 1337
});

//Cal the methods on those different ways.
$('p').myPlugin('someOtherMethod');
&#13;
&#13;
&#13;

答案 1 :(得分:1)

更新,添加{}作为$.extend()

的第一个参数
  

但是,如果要保留两个原始对象,则为   可以通过传递一个空对象作为目标来实现:

     

var object = $.extend({}, object1, object2);

尝试将defaults设为methods的属性,在settings

中定义init
var settings = $.extend({}, methods.defaults, options || {});

在调用this之前将.data()元素settings.each()设置

return this.data(settings).each(function() {})
然后

settings对每个元素都是唯一的;使用$(this).data()访问,如果defaults未作为参数传递给options,则返回$.fn.myPlugin,如果defaults作为参数传递给options则更新$.fn.myPlugin }}

&#13;
&#13;
(function($) {

  var defaults = {
    x: 123,
    y: 321
  };

  var methods = {
    init: function(options) {
      // extend `methods.defaults` with `options`
      var settings = $.extend({}, methods.defaults, options || {});
      return this.data(settings).each(function() {
        //whatever
        console.log("init", this.id, $(this).data());
      });
    },

    someOtherMethod: function() {
      return $(this).each(function() {
        //do whatever and use settings variable as applicable
        console.log("someOtherMethod", this.id, $(this).data());
      })
    },
  };
  // set `defaults` as property of `methods`
  methods.defaults = defaults;

  $.fn.myPlugin = 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 jQuery.myPlugin');
    }
  };

}(jQuery));

$('#id1, #id2').myPlugin({
  x: 111
});
$("#id1").myPlugin({
  y: 222
});
$("#id2").myPlugin({
  y: 333
});
$("#id2").myPlugin("someOtherMethod");
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="id1"></div>
<div id="id2"></div>
&#13;
&#13;
&#13;

jsfiddle http://jsfiddle.net/z28wwnLh/1/

答案 2 :(得分:0)

快速刺伤却赢了这项工作?还是我完全错过了这一点?

(function ($) {

        var defaults = {
            x: 123,
            y: 321
        };

        $.fn.myPlugin = {
            init: function (opts) {
                var settings = $.extend(defaults, opts || {});
                $.each(settings, function (a, b) {
                    console.log(a, ':', b);
                });
            },

            someOtherMethod: function (opts) {
                var settings = $.extend(defaults, opts || {});

                $.each(settings, function (a,b) {
                    console.log(a,':', b);
                });
            }
        };
    }(jQuery));

    $('#id1, #id2').myPlugin.init({ x: 111 });  //Sets x=111 in settings for both
    $('#id3').myPlugin.init({ x: 333 });        //Sets x=333 in settings.
    $('#id3').myPlugin.someOtherMethod({ x: 223 });
    $('#id1').myPlugin.someOtherMethod({ a: 223 });