Создание плагинов jQuery с использованием классов и прототипов
Это хорошая или плохая практика написания плагинов таким образом (с использованием класса и прототипов), каковы недостатки этого кода?
function PluginName(jqueryObject, options) {
}
PluginName.prototype = {
publicMethod:function() {
},
_privateMethod:function() {
}
}
// Initializing
var myPluginInstance = new PluginName($(".mySelector"), {myOption:1});
myPluginInstance.publicMethod();
Ответы
Ответ 1
Обратитесь к jQuery docs на создание плагинов для лучших практик:
- Всегда заверните свой плагин в
(function( $ ){ // plugin goes here })( jQuery );
- Не избыточно обертывайте это ключевое слово в непосредственной близости от вашей функции плагина
- Если вы не возвращаете внутреннее значение из своего плагина, всегда используйте функцию плагина для этого ключевого слова, чтобы поддерживать целостность.
- Вместо того, чтобы требовать большого количества аргументов, передайте свои настройки плагина в литеральном объекте, который может быть расширен по умолчанию по умолчанию.
- Не загромождайте объект jQuery.fn более чем одним пространством имен для каждого плагина.
- Всегда именуют ваши методы, события и данные.
Пример
(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 );
Использование:
$('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
Пример по умолчанию и параметры
(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 );
Использование:
$('div').tooltip({
'location' : 'left'
});
Ответ 2
Во-первых, как сказал Spycho, всегда добавляйте плагин в
(function( $ ){
$.fn.PluginName = function() {
// plugin goes here
};
})( jQuery );
чтобы избежать конфликта с другими библиотеками, использующими знак доллара.
Во-вторых, если вы расширяете объект jQuery.fn
, выбор, который называется с чем-то вроде $("#myDiv")
, передается плагину как this
. Таким образом, вам не нужно передавать выбор в качестве параметра в плагин, как вы это сделали.
В-третьих, это вы сделали правильно, они предлагают, чтобы вы передавали параметры плагину как объект, а не отдельные параметры, поэтому вы можете легко и переопределить значения по умолчанию:
(function( $ ){
$.fn.PluginName = function(options) {
var settings = { myOption: 1 };
if (options) {
$.extend( settings, options );
}
// plugin goes here
};
})( jQuery );
В-четвертых, способ, которым вы создали свой _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 );
В этом случае используются apply
и call
, которые представляют собой причудливые встроенные методы функций для установки диапазона вызовов функций, см. ссылка MDN понять, что там происходит. Таким образом, вы фактически контролируете, какие методы являются общедоступными и частными.
EDIT: Наконец, если вы хотите полностью поддерживать интерфейс среды 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 );
Посмотрите jsFiddle для окончательного рабочего примера.
Ответ 3
Самый простой способ написать jQuery-плагины (особенно если у них есть некоторое внутреннее состояние) - использовать jQuery UI 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/