我已经开始编写一些jQuery插件,并认为使用jQuery插件模板设置我的IDE会很不错。
我一直在阅读本网站上与插件约定,设计等相关的一些文章和帖子。并且我认为我会尝试巩固所有这些。
下面是我的模板,我希望经常使用它,所以很想确保它通常符合jQuery插件设计约定以及是否有多个内部方法(甚至是它的一般设计)的想法会影响性能并且容易发生记忆问题。
(function($)
{
var PLUGIN_NAME = "myPlugin"; // TODO: Plugin name goes here.
var DEFAULT_OPTIONS =
{
// TODO: Default options for plugin.
};
var pluginInstanceIdCount = 0;
var I = function(/*HTMLElement*/ element)
{
return new Internal(element);
};
var Internal = function(/*HTMLElement*/ element)
{
this.$elem = $(element);
this.elem = element;
this.data = this.getData();
// Shorthand accessors to data entries:
this.id = this.data.id;
this.options = this.data.options;
};
/**
* Initialises the plugin.
*/
Internal.prototype.init = function(/*Object*/ customOptions)
{
var data = this.getData();
if (!data.initialised)
{
data.initialised = true;
data.options = $.extend(DEFAULT_OPTIONS, customOptions);
// TODO: Set default data plugin variables.
// TODO: Call custom internal methods to intialise your plugin.
}
};
/**
* Returns the data for relevant for this plugin
* while also setting the ID for this plugin instance
* if this is a new instance.
*/
Internal.prototype.getData = function()
{
if (!this.$elem.data(PLUGIN_NAME))
{
this.$elem.data(PLUGIN_NAME, {
id : pluginInstanceIdCount++,
initialised : false
});
}
return this.$elem.data(PLUGIN_NAME);
};
// TODO: Add additional internal methods here, e.g. Internal.prototype.<myPrivMethod> = function(){...}
/**
* Returns the event namespace for this widget.
* The returned namespace is unique for this widget
* since it could bind listeners to other elements
* on the page or the window.
*/
Internal.prototype.getEventNs = function(/*boolean*/ includeDot)
{
return (includeDot !== false ? "." : "") + PLUGIN_NAME + "_" + this.id;
};
/**
* Removes all event listeners, data and
* HTML elements automatically created.
*/
Internal.prototype.destroy = function()
{
this.$elem.unbind(this.getEventNs());
this.$elem.removeData(PLUGIN_NAME);
// TODO: Unbind listeners attached to other elements of the page and window.
};
var publicMethods =
{
init : function(/*Object*/ customOptions)
{
return this.each(function()
{
I(this).init(customOptions);
});
},
destroy : function()
{
return this.each(function()
{
I(this).destroy();
});
}
// TODO: Add additional public methods here.
};
$.fn[PLUGIN_NAME] = function(/*String|Object*/ methodOrOptions)
{
if (!methodOrOptions || typeof methodOrOptions == "object")
{
return publicMethods.init.call(this, methodOrOptions);
}
else if (publicMethods[methodOrOptions])
{
var args = Array.prototype.slice.call(arguments, 1);
return publicMethods[methodOrOptions].apply(this, args);
}
else
{
$.error("Method '" + methodOrOptions + "' doesn't exist for " + PLUGIN_NAME + " plugin");
}
};
})(jQuery);
提前致谢。
答案 0 :(得分:28)
前段时间我根据我读过的博客文章构建了一个插件生成器:http://jsfiddle.net/KeesCBakker/QkPBF/。它可能有用。这是相当基本和直接的。任何评论都会非常受欢迎。
您可以分叉自己的发电机并根据需要进行更改。
聚苯乙烯。这是生成的正文:
(function($){
//My description
function MyPluginClassName(el, options) {
//Defaults:
this.defaults = {
defaultStringSetting: 'Hello World',
defaultIntSetting: 1
};
//Extending options:
this.opts = $.extend({}, this.defaults, options);
//Privates:
this.$el = $(el);
}
// Separate functionality from object creation
MyPluginClassName.prototype = {
init: function() {
var _this = this;
},
//My method description
myMethod: function() {
var _this = this;
}
};
// The actual plugin
$.fn.myPluginClassName = function(options) {
if(this.length) {
this.each(function() {
var rev = new MyPluginClassName(this, options);
rev.init();
$(this).data('myPluginClassName', rev);
});
}
};
})(jQuery);
答案 1 :(得分:26)
答案 2 :(得分:0)
我一直在谷歌上搜索,所以,我必须发表一些想法:首先我同意@Raynos。
那里试图构建jQuery插件的代码最多......不是插件!它只是存储在内存中的一个对象,它由节点/元素的data属性引用。这是因为应该看到jQuery并将其作为一个工具与一个类库一起使用(以补救来自OO架构的js不一致)来构建更好的代码,是的,这一点都不错!
如果您不喜欢古典OO行为,请坚持使用像clone这样的原型库。
那么我们的选择到底是什么?
假设以下方案解决了问题(请参阅此问题的复杂性:Which jQuery plugin design pattern should I use?):
我们有节点A,B和C,它们将对象引用存储到
中data
属性其中一些将信息存储在公共和私人可访问的 内部对象 中, 这些对象的某些类与继承相关联, 所有这些节点还需要一些私有的和公共 单例 才能发挥最佳效果。
我们会怎么做?见图:
classes : | A B C
------------------case 1----------
members | | | |
of | v v v
an object | var a=new A, b=new B, c=new C
at | B extends A
node X : | a, b, c : private
------------------case 2---------
members | | | |
of | v v v
an object | var aa=new A, bb=new B, cc=new C
at | BB extends AA
node Y : | aa, bb, cc : public
-------------------case 3--------
members | | | |
of | v v v
an object | var d= D.getInstance() (private),
at | e= E.getInstance() (public)
node Z : | D, E : Singletons
正如你所看到的,每个节点都引用一个对象 - 一个jQuery方法 - 但是这些对象变化很大;它们包含存储在其中的不同数据的对象属性,甚至单个内存应该是...单个内存,就像对象的原型函数一样。我们不希望属于class A
的每个对象的函数在每个节点的对象中重复 在内存中重复 !
在我回答之前 看到我在jQuery插件中看到的一种常见方法 - 其中一些非常受欢迎,但我不说名字:
(function($, window, document, undefined){
var x = '...', y = '...', z = '...',
container, $container, options;
var myPlugin = (function(){ //<----the game is lost!
var defaults = {
};
function init(elem, options) {
container = elem;
$container = $(elem);
options = $.extend({}, defaults, options);
}
return {
pluginName: 'superPlugin',
init: function(elem, options) {
init(elem, options);
}
};
})();
//extend jquery
$.fn.superPlugin = function(options) {
return this.each(function() {
var obj = Object.create(myPlugin); //<---lose, lose, lose!
obj.init(this, options);
$(this).data(obj.pluginName, obj);
});
};
}(jQuery, window, document));
我正在观看Ben Benman的http://www.slideshare.net/benalman/jquery-plugin-creation处的一些幻灯片,他在第13张幻灯片中将 对象文字 称为 单身人士< / em> ,这只是让我失望:这就是上面的插件所做的,它创建了一个单独的 没有机会 来改变它的内部状态! !!
此外,在jQuery部分,它将 公共引用 存储到每个节点!
我的解决方案使用 工厂 来保持内部状态并返回一个对象,并且可以使用 类扩展 库并拆分成不同的文件:
;(function($, window, document, undefined){
var myPluginFactory = function(elem, options){
........
var modelState = {
options: null //collects data from user + default
};
........
function modeler(elem){
modelState.options.a = new $$.A(elem.href);
modelState.options.b = $$.B.getInstance();
};
........
return {
pluginName: 'myPlugin',
init: function(elem, options) {
init(elem, options);
},
get_a: function(){return modelState.options.a.href;},
get_b: function(){return modelState.options.b.toString();}
};
};
//extend jquery
$.fn.myPlugin = function(options) {
return this.each(function() {
var plugin = myPluginFactory(this, options);
$(this).data(plugin.pluginName, plugin);
});
};
}(jQuery, window, document));
答案 3 :(得分:0)
这样的事情怎么样?它更加清晰但是如果你能够改进它而不会过于复杂,那么很高兴听到你。
// jQuery plugin Template
(function($){
$.myPlugin = function(options) { //or use "$.fn.myPlugin" or "$.myPlugin" to call it globaly directly from $.myPlugin();
var defaults = {
target: ".box",
buttons: "li a"
};
options = $.extend(defaults, options);
function logic(){
// ... code goes here
}
//DEFINE WHEN TO RUN THIS PLUGIN
$(window).on('load resize', function () { // Load and resize as example ... use whatever you like
logic();
});
// RETURN OBJECT FOR CHAINING
// return this;
// OR FOR FOR MULTIPLE OBJECTS
// return this.each(function() {
// // Your code ...
// });
};
})(jQuery);
// USE EXAMPLE with default settings
$.myPlugin(); // or run plugin with default settings like so.
// USE EXAMPLE with overwriten settings
var options = {
target: "div.box", // define custom options
buttons: ".something li a" // define custom options
}
$.myPlugin(options); //or run plugin with overwriten default settings