attaching a class to a jQuery object(将类附加到 jQuery 对象)
问题描述
我正在为如何最好地结合 javascript 类和 jQuery 插件而苦苦挣扎.这个问题不是很具体,我希望的是指向更多资源的指针.
I'm struggling with how best to combine javascript Classes and jQuery plugins. This question isn't very specific, what I'm hoping for is pointers to more resources.
基本上,我想将状态数据和私有方法存储在一个类中,然后扩展我调用插件的每个 jQuery 对象以具有这些私有方法和属性.这样我就可以在插件内部直接调用 jQuery 对象的方法.
Basically, I want to store state data and private methods in a class, and then extend each jQuery object which I call my plugin on to have those private methods and properties. Such that inside the plugin I can call methods directly off the jQuery object.
我阅读了 jQuery 插件设计模式(常见做法?)用于处理私有函数,特别是大卫的回答,但是每次都会初始化一个新类,因此不能用于保存对象的状态.
I read jQuery plugin design pattern (common practice?) for dealing with private functions, specifically David's answer, however this initializes a new Class each time, and thus can't be used to save the state of the object.
我还发现 http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/,建议创建一个类,然后将其存储在 .data() 中.
I also found http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/, which recommends creating a class and then storing it in .data().
我认为理想情况下我想要的代码看起来像
I think ideally what I want to end up with is code that looks like
(function( $ ){
var methods = {
init : function( options ) { // Initialize each object with a state and private methods },
show : function( ) {
// testFoo() is a private method that checks the element's state
if(this.testFoo()){
// Relying on jQuery's html() method
this.html() = this.fooTemplate();
}
}
};
// Boiler plate plugin from http://docs.jquery.com/Plugins/Authoring
$.fn.myPlugin = 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.myPlugin' );
}
};
})( jQuery );
最后,我似乎无法将私有方法直接烘焙到插件中,因为像testFoo()"这样的方法将返回一个布尔值,因此不可链接.
Finally, it doesn't seem like I can bake the private methods into the plugin directly because methods like "testFoo()" will return a boolean, and therefore aren't chainable.
想法?我以正确的方式接近这个吗?我应该使用另一种设计模式吗?也许根本不使用 jQuery 插件架构?
Thoughts? Am I approaching this the right way? Is there another design pattern I should be using? Perhaps not using jQuery plugin architecture at all?
推荐答案
这是一个建议的解决方案.它结合了几种不同的方法(John Resig 的继承模型和 Alex Saxton 的插件继承模型).
Here's a proposed solution. It combines few different approaches (John Resig's inheritance model and Alex Saxton's plugin inheritance model).
定义您的可继承插件:
(function ($) {
My.Plugin = Class.extend({
/*
* Initialization (constructor)
*/
init: function (element, meta) {
var $meta = $.extend({ name: "pluginName" }, meta);
// Call the base constructor
this._super(element, $meta);
// TODO: Add custom initialization code like the following:
// this._testButton = $('.testButton', element).get(0);
},
/*
* Public methods
*/
show: function() {
alert('This is a public method');
},
/*
* Private methods
*/
// DEMO: Overriding the base _paint method:
_paint: function () {
// "this._super()" is available in all overridden methods
// and refers to the base method.
this._super();
alert('TODO: implement myPlugin._paint!');
}
});
// Declare this class as a jQuery plugin
$.plugin('my_plugin', My.Plugin);
})(jQuery);
定义基类
(function () {
var initializing = false, fnTest = /xyz/.test(function () { xyz; }) ? /_super/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function () { };
// Create a new Class that inherits from this class
Class.extend = function (prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] =
typeof prop[name] == "function"
&& typeof _super[name] == "function"
&& fnTest.test(prop[name])
? (function (name, fn) {
return function () {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name])
: prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.init)
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
插件创建
(function ($) {
// The "inheritance plugin" model
// [http://alexsexton.com/?p=51][1]
$.plugin = function (name, object) {
$.fn[name] = function (options) {
var instance = $.data(this, name, new object(this, options));
return instance;
};
};
})(jQuery);
从 javascript 调用你的插件:
Calling your plugin from javascript:
$('#someElem').my_plugin({options: {}, data: {} /* you can modify your plugin code to accept anything *
本文标题为:将类附加到 jQuery 对象


基础教程推荐
- Karma-Jasmine:如何正确监视 Modal? 2022-01-01
- 在 JS 中获取客户端时区(不是 GMT 偏移量) 2022-01-01
- 我什么时候应该在导入时使用方括号 2022-01-01
- 悬停时滑动输入并停留几秒钟 2022-01-01
- 在for循环中使用setTimeout 2022-01-01
- 动态更新多个选择框 2022-01-01
- 当用户滚动离开时如何暂停 youtube 嵌入 2022-01-01
- 有没有办法使用OpenLayers更改OpenStreetMap中某些要素 2022-09-06
- 响应更改 div 大小保持纵横比 2022-01-01
- 角度Apollo设置WatchQuery结果为可用变量 2022-01-01