javascript 使用类和原型编写 jQuery 插件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7149239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Writing jQuery Plugins Using Classes and Prototypes
提问by Marvin3
Is it good or bad practise writing plugins this way(using class and prototypes), what are disadvatages of this code?
以这种方式编写插件(使用类和原型)是好是坏,这段代码的缺点是什么?
function PluginName(jqueryObject, options) {
}
PluginName.prototype = {
publicMethod:function() {
},
_privateMethod:function() {
}
}
// Initializing
var myPluginInstance = new PluginName($(".mySelector"), {myOption:1});
myPluginInstance.publicMethod();
回答by Spycho
See the jQuery docs on plugin authoringfor best practices:
- Always wrap your plugin in
(function( $ ){ // plugin goes here })( jQuery );
- Don't redundantly wrap the this keyword in the immediate scope of your plugin's function
- Unless you're returning an intrinsic value from your plugin, always have your plugin's function return the this keyword to maintain chainability.
- Rather than requiring a lengthy amount of arguments, pass your plugin settings in an object literal that can be extended over the plugin's defaults.
- Don't clutter the jQuery.fn object with more than one namespace per plugin.
- Always namespace your methods, events and data.
- 始终包装您的插件
(function( $ ){ // plugin goes here })( jQuery );
- 不要在插件函数的直接范围内多余地包装 this 关键字
- 除非你从你的插件中返回一个内在的值,否则总是让你的插件的函数返回 this 关键字以保持可链接性。
- 不需要大量的参数,而是将您的插件设置传递到一个可以扩展到插件默认值的对象文字中。
- 不要将 jQuery.fn 对象与每个插件的多个命名空间混为一谈。
- 始终命名您的方法、事件和数据。
Example
例子
(function( $ ){
var methods = {
init : function( options ) { // THIS },
show : function( ) { // IS },
hide : function( ) { // GOOD },
update : function( content ) { // !!! }
};
$.fn.tooltip = function( method ) {
// Method calling logic
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.tooltip' );
}
};
})( jQuery );
Usage:
用法:
$('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
Defaults and Options Example
默认值和选项示例
(function( $ ){
$.fn.tooltip = function( options ) {
var settings = {
'location' : 'top',
'background-color' : 'blue'
};
return this.each(function() {
// If options exist, lets merge them
// with our default settings
if ( options ) {
$.extend( settings, options );
}
// Tooltip plugin code here
});
};
})( jQuery );
Usage:
用法:
$('div').tooltip({
'location' : 'left'
});
回答by nwellcome
First, as Spycho said, always wrap your plugin in
首先,正如 Spycho 所说,始终将您的插件包装在
(function( $ ){
$.fn.PluginName = function() {
// plugin goes here
};
})( jQuery );
to avoid conflict with other libraries that use the dollar sign.
避免与其他使用美元符号的库发生冲突。
Second, if you extend the jQuery.fn
object the selection called with something like $("#myDiv")
is passed to the plugin as this
. This way you don't have to pass the selection as a parameter to the plugin as you've done.
其次,如果您扩展jQuery.fn
对象,则使用类似$("#myDiv")
名称调用的选择将作为this
. 这样你就不必像你所做的那样将选择作为参数传递给插件。
Third, this you did correctly, they suggest that you pass options to the plugin as an object rather than individual parameters, this is so you can easily have and override defaults:
第三,你做对了,他们建议你将选项作为对象而不是单个参数传递给插件,这样你就可以轻松拥有和覆盖默认值:
(function( $ ){
$.fn.PluginName = function(options) {
var settings = { myOption: 1 };
if (options) {
$.extend( settings, options );
}
// plugin goes here
};
})( jQuery );
Fourth, the way you've created your _privateMethod
doesn't actually make it private, to do so you could follow the pattern jQuery suggests in the plugin authoring guidelines
第四,您创建的方式_privateMethod
实际上并未将其设为私有,为此您可以遵循 jQuery 在插件创作指南中建议的模式
(function( $ ){
var methods = {
publicMethod: function(options) {
var settings = { myOption: 1 };
if (options) {
$.extend( settings, options );
}
},
_privateMethod: function() {}
}
$.fn.PluginName = function(methodName, options) {
// use some logic to control what methods are public
if (methodName == "publicMethod") {
return publicMethod.apply(this, Array.prototype.slice.call( arguments, 1 ));
}
};
})( jQuery );
This uses apply
and call
which are fancy built-in methods of functions for setting the scope of function calls, see the MDN referenceto understand what is going on there. This way you actually have control over which methods are public versus private.
这使用apply
和call
哪些是用于设置函数调用范围的精美内置函数方法,请参阅MDN 参考以了解那里发生的事情。通过这种方式,您实际上可以控制哪些方法是公共的还是私有的。
EDIT:Finally, if you want to completely maintain jQuery's fluid interface and have your plugin both accept the selection passed by $()
and pass it on, in other words, be chainable, your methods need to return the collection of objects they were given:
编辑:最后,如果您想完全维护 jQuery 的流畅界面并使您的插件既接受传递的选择$()
又传递它,换句话说,是可链接的,您的方法需要返回给定对象的集合:
(function( $ ){
var methods = {
publicMethod: function(options) {
var settings = { myOption: 1 };
if (options) {
$.extend( settings, options );
}
return this.each(function() {
this.value = (this.value * 1) + settings.myOption;
});
},
_privateMethod: function() {}
}
$.fn.PluginName = function(methodName, options) {
// use some logic to control what methods are public
if (methodName == "publicMethod") {
return methods.publicMethod.apply(this, Array.prototype.slice.call( arguments, 1 ));
}
};
})( jQuery );
See this jsFiddlefor the final working example.
有关最终工作示例,请参阅此jsFiddle。
回答by kolobok
The easiest way to write jQuery plugins (especially if they have some internal state) is to use jQuery UI Widget Factory.
编写 jQuery 插件的最简单方法(尤其是当它们有一些内部状态时)是使用 jQuery UI Widget Factory。
I wouldn't recommend to reinvent the wheel and write lots of boilerplate code by yourself.
我不建议自己重新发明轮子并编写大量样板代码。
https://learn.jquery.com/jquery-ui/widget-factory/why-use-the-widget-factory/https://learn.jquery.com/plugins/stateful-plugins-with-widget-factory/
https://learn.jquery.com/jquery-ui/widget-factory/why-use-the-widget-factory/ https://learn.jquery.com/plugins/stateful-plugins-with-widget-factory/