我一直在使用以下设计模式来创建jQuery插件。我很确定我从jQuery主页获得了这个概念,但它似乎不再在那里发布了。
我最近尝试访问除settings
方法之外的方法(即someOtherMethod ()
)中的init()
变量,并且由于未定义settings
而遇到错误。我看到原因settings
与init()
方法隔离。
如果我将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.
答案 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;
答案 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
}}
(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;
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 });