[英]How to extend a jquery plugin's public methods through its prototype?
How can I extend a plugin's public methods its prototype ? 如何扩展插件的公共方法的原型 ?
For instance, I have method1 in my plugin, and I want to add another and more through its .prototype
. 例如,我的插件中有method1,我想通过它的
.prototype
添加另一个和更多。 Is it possible? 可能吗?
var extensionMethods = {
method2: function(){
return this;
}
};
$.fn.MyPlugin.prototype = extensionMethods;
console.log($(".element").MyPlugin());
result, 结果,
Object { Element={...}, Options={...}, method1=function()}
Ideally, 理想的情况下,
Object { Element={...}, Options={...}, method1=function(), method2=function(), method2function()}
my plugin boilerplate, 我的插件样板,
(function ($) {
// Create the plugin name and defaults once
var pluginName = 'MyPlugin';
// Attach the plugin to jQuery namespace.
$.fn[pluginName] = function(PublicOptions) {
// Set private defaults.
var Defaults = {
param1: 'param1',
param2: 'param2',
onSuccess: function(){}
};
// Do a deep copy of the options.
var Options = $.extend(true, {}, Defaults, PublicOptions);
// Define a functional object to hold the api.
var PluginApi = function(Element, Options) {
this.Element = Element;
this.Options = Options;
};
// Define the public api and its public methods.
PluginApi.prototype = {
method1: function(PublicOptions) {
// Process the options.
var Options = $.extend(true, {}, this.Options, PublicOptions);
return this.Options;
}
};
//Create a new object of api.
return new PluginApi(this, Options);
};
})(jQuery);
Any ideas? 有任何想法吗?
I think the best structure you can do in this case would not involve prototypes at all. 我认为在这种情况下你可以做的最好的结构根本不涉及原型。 Check this plugin base:
检查这个插件库:
(function($) {
// Set private defaults.
var Defaults = {
param1: 'param1',
param2: 'param2',
onSuccess: function() {}
};
// Define the public api and its public methods.
var PluginApi = {
extend: function(name, method) {
PluginApi[name] = method;
return this;
},
init: function(PublicOptions) {
// Do a deep copy of the options.
var Options = $.extend(true, {}, Defaults, PublicOptions);
return this.each(function() {
console.log('set up plugin logic', this.tagName);
});
},
method1: function() {
console.log('called: method1');
return this;
}
};
// Create the plugin name and defaults once
var pluginName = 'MyPlugin';
// Attach the plugin to jQuery namespace.
$.fn[pluginName] = function(method) {
if (PluginApi[method]) {
return PluginApi[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if (typeof method === 'object' || !method) {
return PluginApi.init.apply(this, arguments);
}
else {
$.error('Method ' + method + 'does not exist');
}
};
})(jQuery);
This plugin structure allows you to chain methods as expected: 此插件结构允许您按预期链接方法:
$('h1').MyPlugin('method1').css('color', 'red');
In case of the need to use non-existent method you could do this: 如果需要使用不存在的方法,您可以这样做:
// Extend plugin "prototype" with method2 and use it
$('h1, h2').MyPlugin('extend', 'method2', function(prop, value) {
return this.css(prop, value);
}).MyPlugin('method2', 'color', 'green');
Check usage example in the demo below. 检查以下演示中的使用示例。
(function($) { // Set private defaults. var Defaults = { param1: 'param1', param2: 'param2', onSuccess: function() {} }; // Define the public api and its public methods. var PluginApi = { extend: function(name, method) { PluginApi[name] = method; return this; }, init: function(PublicOptions) { // Do a deep copy of the options. var Options = $.extend(true, {}, Defaults, PublicOptions); return this.each(function() { console.log('set up plugin logic', this.tagName); }); }, method1: function() { console.log('called: method1'); return this; } }; // Create the plugin name and defaults once var pluginName = 'MyPlugin'; // Attach the plugin to jQuery namespace. $.fn[pluginName] = function(method) { if (PluginApi[method]) { return PluginApi[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return PluginApi.init.apply(this, arguments); } else { $.error('Method ' + method + 'does not exist'); } }; })(jQuery); // Call existen method1: should make h1 and h2 red $('h1, h2').MyPlugin('method1').css('color', 'red'); // Call non-existent method2: should throw error in console try { $('h1, h2').MyPlugin('method2').css('color', 'green'); } catch (e) { // Extend "plugin" prototype with method2 $('h1, h2').MyPlugin('extend', 'method2', function(prop, value) { return this.css(prop, value); }).MyPlugin('method2', 'color', 'green'); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h1>H1</h1> <h2>H2</h2>
Or it may be more optimal to define a static method extend
within $[pluginName]
namespace: 或者在
$[pluginName]
命名空间中定义静态方法extend
可能更$[pluginName]
:
// Attach the plugin to jQuery namespace.
$.fn[pluginName] = function(method) {
if (PluginApi[method]) {
return PluginApi[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if (typeof method === 'object' || !method) {
return PluginApi.init.apply(this, arguments);
}
else {
$.error('Method ' + method + 'does not exist');
}
};
$[pluginName] = {};
$[pluginName].extend = function(name, method) {
PluginApi[name] = method;
};
and then use it like this when necessary to add additional methods: 然后在必要时使用它来添加其他方法:
$.MyPlugin.extend('method2', function(prop, value) {
return this.css(prop, value);
});
$('h1, h2').MyPlugin('method2', 'color', 'green');
You can't extend the prototype outside because you use hidden object PluginApi. 您无法将原型扩展到外部,因为您使用隐藏对象PluginApi。
You can try to store PluginApi outside of a plugin function: 您可以尝试在插件函数之外存储PluginApi:
$[pluginName] = function(Element, Options) {
this.Element = Element;
this.Options = Options;
};
$[pluginName].prototype = {
method1: function(PublicOptions) {
// Process the options.
var Options = $.extend(true, {}, this.Options, PublicOptions);
return this.Options;
}
};
$.fn[pluginName] = function(PublicOptions) {
// Set private defaults.
var Defaults = {
param1: 'param1',
param2: 'param2',
onSuccess: function(){}
};
// Do a deep copy of the options.
var Options = $.extend(true, {}, Defaults, PublicOptions);
return new $[pluginName](this, Options);
};
and then you can extend the the prototype: 然后你可以扩展原型:
$.MyPlugin.prototype.method2 = function() {
return this;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.