使用配置设置创建 jQuery 插件
Create jQuery plugin with configuration settings
我一直在使用以下设计模式来创建 jQuery 插件。我很确定我是从 jQuery 主页上得到这个概念的,但是,它似乎不再在那里发布。
我最近试图在 init()
方法以外的方法(即 someOtherMethod ()
)中访问 settings
变量,但遇到错误,因为 settings
不是定义。我认为原因是 settings
与 init()
方法隔离。
如果我将 settings
移动到此方法之外,我可以从不同的方法访问它,但是,应用插件时的每个实例都不会有其唯一的设置变量,这是不可接受的。例如,$('#id1, #id2').myPlugin({x:111});
应该有一个共同的 settings
变量,但是 $('#id1').myPlugin({x:111}); $('#id2').myPlugin({x:222});
应该每个都有其独特的设置变量。
以下面的设计模式为起点,如何从与插件关联的所有方法访问 settings
变量,同时在每次应用插件时都有一个唯一的 settings
变量?
(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.
您将要保存每个元素的设置对象,以便这些设置将在不同的选择器中保持不变。执行此操作的最佳方法是使用 jQuery.data
将设置对象附加到元素。这样,无论元素是如何选择的,每次选择元素时设置都会保留。
然后,在 someOtherMethod
的 .each
调用中,您可以使用元素上的 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');
<p class="group-1">group 1</p>
<p class="group-1">group 1</p>
<p class="group-2">group 2</p>
<p class="group-2">group 2</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
已更新,添加 {}
作为 $.extend()
的第一个参数
If, however, you want to preserve both of the original objects, you
can do so by passing an empty object as the target:
var object = $.extend({}, object1, object2);
尝试将 defaults
设置为 methods
的 属性,在 init
中定义 settings
var settings = $.extend({}, methods.defaults, options || {});
在调用 .each()
之前用 settings
设置 this
元素 .data()
return this.data(settings).each(function() {})
settings
对每个元素都是唯一的;使用 $(this).data()
可访问,如果 options
未作为参数传递给 $.fn.myPlugin
则返回 defaults
,如果 options
作为参数传递给 [=29] 则更新 defaults
=]
(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");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="id1"></div>
<div id="id2"></div>
jsfiddle http://jsfiddle.net/z28wwnLh/1/
只是快速尝试一下,但这行不通吗?还是我完全忽略了这一点?
(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 });
我一直在使用以下设计模式来创建 jQuery 插件。我很确定我是从 jQuery 主页上得到这个概念的,但是,它似乎不再在那里发布。
我最近试图在 init()
方法以外的方法(即 someOtherMethod ()
)中访问 settings
变量,但遇到错误,因为 settings
不是定义。我认为原因是 settings
与 init()
方法隔离。
如果我将 settings
移动到此方法之外,我可以从不同的方法访问它,但是,应用插件时的每个实例都不会有其唯一的设置变量,这是不可接受的。例如,$('#id1, #id2').myPlugin({x:111});
应该有一个共同的 settings
变量,但是 $('#id1').myPlugin({x:111}); $('#id2').myPlugin({x:222});
应该每个都有其独特的设置变量。
以下面的设计模式为起点,如何从与插件关联的所有方法访问 settings
变量,同时在每次应用插件时都有一个唯一的 settings
变量?
(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.
您将要保存每个元素的设置对象,以便这些设置将在不同的选择器中保持不变。执行此操作的最佳方法是使用 jQuery.data
将设置对象附加到元素。这样,无论元素是如何选择的,每次选择元素时设置都会保留。
然后,在 someOtherMethod
的 .each
调用中,您可以使用元素上的 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');
<p class="group-1">group 1</p>
<p class="group-1">group 1</p>
<p class="group-2">group 2</p>
<p class="group-2">group 2</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
已更新,添加 {}
作为 $.extend()
If, however, you want to preserve both of the original objects, you can do so by passing an empty object as the target:
var object = $.extend({}, object1, object2);
尝试将 defaults
设置为 methods
的 属性,在 init
settings
var settings = $.extend({}, methods.defaults, options || {});
在调用 .each()
settings
设置 this
元素 .data()
return this.data(settings).each(function() {})
settings
对每个元素都是唯一的;使用 $(this).data()
可访问,如果 options
未作为参数传递给 $.fn.myPlugin
则返回 defaults
,如果 options
作为参数传递给 [=29] 则更新 defaults
=]
(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");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="id1"></div>
<div id="id2"></div>
jsfiddle http://jsfiddle.net/z28wwnLh/1/
只是快速尝试一下,但这行不通吗?还是我完全忽略了这一点?
(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 });