前言:
所有的jQuery UI的控件和交换都是基于一个简单的,可重用的jQuery UI控件工厂。它使用一个一致的api作为一个插件可伸缩的基础,来生产复杂,有状态的插件。它被设计为不仅仅作为jQuery UI控件的一部分,而且可以作为不想重构公共组件生成面向对象组件的开发者的一般工具。它不依赖其他的jQuery UI,但是大多数的jQuery UI依赖它。
它是什么
控件的工厂是一个在全局jQuery对象上的一个简单的方法,它有2个或者3个参数。
jQuery.widget( "namespace.widgetname", /* 可选的 - 一个已经存在的组件的prototype来继承 */, /* 传递到组件prototype有一系列的属性组成的对象*/ {...} );
第一个参数是一个包含一个命名空间和组件名称的字符串,通过"."来分割。命名空间必须有,它指向widget prototype存储的全局jQuery对象(fuck这什么意思啊) . 如果命名空间没有,widget factory将会为你生成。widget name是插件函数和原型的真实名称,比如: jQuery.widget( "demo.multi", {...} ) 将会生成 jQuery.demo , jQuery.demo.multi , and jQuery.demo.multi.prototype .
第二个参数(可选)是 widget prototype继承于什么对象。例如jQuery UI有一个“mouse”的插件,它可以作为其他的插件提供的基础。为了实现这个所有的基于mouse的插件比如draggable, droppable可以这么做: jQuery.widget( "ui.draggable", $.ui.mouse, {...} );如果没有这个参数,widget默认继承自“base widget” jQuery.Widget(注意jQuery.widget 和 jQuery.Widget不同) 。
widget factory的最后一个参数是一个对象文字,它会转化为所有widget实例的prototype。widget factory会生成属性链,连接到她继承的widget的prototype。一直到最基本的 jQuery.Widget。
一旦你调用jQuery.widget,它会在jQuery prototype ( jQuery.fn )上生成一个新的可用方法对应于widget的名字,比如我们这个例子jQuery.fn.multi。 .fn方法是包含Dom元素的jquery对象和你生成的 widget prototyp实例的接口,为每一个jQuery对象生成一个新的widget的实例。
更多一点
在Plugin Authoring Guidelines(英文:http://docs.jquery.com/Plugins/Authoring 中文:http://xxh123.iteye.com/blog/1103545)中说了很多实现有状态,面向对象插件的方法。但是它没有给避免普通的plumbing任务提供方便。widget factory给你提供了 jQuery UI的API,与你的插件的实例来交互,并且抽象了一系列的重复任务。
通过namespace和name生成一个伪选择器,可以这样查询:$( ":demo-multi" )。
通过使用jQuery.widget.bridge来实现。
默认的值是暴露的,所以用户可以修改默认的值
- 通过$("#something").data("pluginname")访问插件的实例
实例对象的属性this.element是一个包含Dom元素的jQuery对象的引用,所以从对象到元素或者元素到对象的转换比较的简单。
- 通过在jQuery prototype上的方法和字符串可以访问widget的methods: $("#something").multi("refresh")。或 者直接访问实例自己:$( "#something" ).data( "multi" ).refresh()。
- 链式的转发回调插件,用户可以触发this._trigger( "clear" )
用户可以定义一个选项
$("#something").multi({clear: function(event) }});
或者使用.bind()
$("#something").bind("multiclear", function( event ) {});
实例化后简化和修改插件选项的方法:
$( "#something" ).multi( "option", "clear" , function ( event ) { alert( "I cleared the multiselect!" ); } );
很容易enable或者disable widget,或者整体实力的销毁和返回元素的元素状态。
构建自己的属性
基础
你给widget factory传递的对象,可以作为你需要的复杂的widget属性。但是最起码需要default options , and basic _create , _setOption , and destroy callbacks。
$.widget( "demo.multi", {
// These options will be used as defaults
options: {
clear: null
},
// Set up the widget
_create: function() {
},
// Use the _setOption method to respond to changes to options
_setOption: function( key, value ) {
switch( key ) {
case "clear":
// handle changes to clear option
break;
}
// In jQuery UI 1.8, you have to manually invoke the _setOption method from the base widget
$.Widget.prototype._setOption.apply( this, arguments );
// In jQuery UI 1.9 and above, you use the _super method instead
this._super( "_setOption", key, value );
},
// Use the destroy method to clean up any modifications your widget has made to the DOM
destroy: function() {
// In jQuery UI 1.8, you must invoke the destroy method from the base widget
$.Widget.prototype.destroy.call( this );
// In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method
}
});
}( jQuery ) );
在方法中包装
传递的对象也许也需要包含方法来处理各种各样的插件具体的功能。比如创建和增加新元素或者处理事件。你可以使用一些别的方法来处理每一个功能 而不是所以的代码都放在_create中。这样你可以避免当功能修改的时候重复代码。比如hypothetical的控件增强了<select multiple>,它必须迭代select中的option选项,而且生成对应的<li> in aproxy </li>,这个可以在_create方法中实现,像这样:
_create: function() {
var self = this;
this.list = $( "<ul>" ).insertAfter( this.element );
this.element.hide().find( "option" ).each(function( i, el ) {
var $el = $( el ),
text = $( el ).text(),
item = $( "<li class='multi-option-item'>" + text + "</li>" );
item.appendTo( self.list ).click(function(){
console.log( $el.val() );
});
});
}
不幸的是把代码留在_create,会造成原始的<option>元素和list items之间的管理的困难。或者在控件实例化后处理从原始的<select>增加或者删除<option>状态的问题。代替我们 使用一个refresh方法来负责专门处理这一功能,并在_create中引用。我们当然可以把在元素上处理点击事件的逻辑独立。而且我们使用delegate来避免当新元素创建的时候的重复绑定。
_create: function() {
this.list = $( "<ul>" )
.insertAfter( this.element )
.delegate( "li.multi-option-item", "click", $.proxy( this._itemClick, this ) );
this.element.hide();
this.refresh();
},
refresh: function() {
// Keep track of the generated list items
this.items = this.items || $();
// Use a class to avoid working on options that have already been created
this.element.find( "option:not(.demo-multi-option)" ).each( $.proxy(function( i, el ) {
// Add the class so this option will not be processed next time the list is refreshed
var $el = $( el ).addClass( "demo-multi-option" ),
text = $el.text(),
// Create the list item
item = $( "<li class='multi-option-item'>" + text + "</li>" )
.data( "option.multi", el )
.appendTo( this.list );
// Save it into the item cache
this.items = this.items.add( item );
},this));
// If the the option associated with this list item is no longer contained by the
// real select element, remove it from the list and the cache
this.items = this.items.filter( $.proxy(function( i, item ) {
var isInOriginal = $.contains( this.element[0], $.data( item, "option.multi" ) );
if ( !isInOriginal ) {
$( item ).remove();
}
return isInOriginal;
}, this ));
},
_itemClick: function( event ) {
console.log( $( event.target ).val() );
}
私有和公共方法
你也许注意到一些方法以“_”开头,一些不是。以“_”开头的方法被当作jQuery UI的私有方法。控件工厂将会阻止$.fn调用私有方法。 $( "#something" ).multi( "_create" )会扔出一个异常。方法直接在widget prototype上存在,然而这个只是协定的私有方法。当我们使用widget的实力的data()方法的时候,我们可以直接访问他们$("#something" ).data( "multi" )._create() . 那么怎么做更好的?如果控件的使用者需要一个特别的方法的功能,使用public。在一点上举个例子:如果用户处理原始的<select>中的元素,我们必须为来提供方便来更新代理。另一方面,一个plumbing方法来处理widget创建的代理元素。比如 _itemClick,它只是中间使用,所以使用私有方法。
属性
this.element
它是插件的实例化元素。比如,如果你是使用$("#foo").myWidget(),让后在你你的控件对象中this.element是一个包含id为foo的元素的jquery对象。当你选择了多了元素,并在集合上调用.myWidget(),会为每一个元素生成一个插件的实例,总而言之,this.element总是只包含一个元素。
this.options
options被用作插件的配置,用户提供的options会自动的覆盖 $.demo.multi.prototype.options中的默认的options。
this.namespace
就是插件的命名空间,一般不需要在独立插件的内部使用。
this.name
就是插件的名字,比如我们的"multi",比命名空间有用多了,但是在一般在独立插件的内部也不使用。
this.widgetEventPrefix
它被用来决定事件的名称和插件提供的callbacks的关联。比如dialog有一个close的callback,当close的callback被执行的时候,一个dialogclose的事件被触发。事件的名称和事件的prefix+callback的名称。widgetEventPrefix 默认就是控件的名称,但是如果事件需要不同的名称也可以被重写。比如一个用户开始拖拽一个元素
我们不想使用draggablestart作为事件的名称,我们想使用dragstart,所以我们可以重写事件的prefix。如果callback的名称和事件的prefix相同,事件的名称将不会是prefix。它阻止像dragdrag一样的时间名称。
this.widgetBaseClass
在widget里在元素上生成类名非常有用,比如如果你想标记一个元素是否有效,你可以 element.addClass( this.widgetBaseClass + "-active" ),这个在独立的插件中没有需要,因为你可以非常容易的使用.addClass( "demo-multi-active" )。但是它更多的使用在控件的内部和抽象的插件比如$.ui.mouse.
方法:
_create
这个是创建和你的空间相关的所有的东西,比如创建元素,绑定事件。这个方法在实例化后立刻运行一次。
_init
你的控件在调用时没有参数或者一个options参数,这个方法被调用。它可以在_create调用后第一次调用。也可以在控件生成后的任何时间调用那样,_init允许你重写初始化,而不必强制用户调用destroy->create的循环.
destroy
这个destory插件的对象和其他必要的清理。任何插件造成的修改必须被remove和destroy。包括消除类,解绑定事件,销毁生成的元素。控件工厂提供了一个开始的地方,但是应该满足所有的独立插件的需要。
option
用来在实例化后初始和设置options。方法的用法和jquery的.css()或.attr()一样。可以指定一个名字来获取值和设置值。这个方法通常被称作_setOptions 所以这个方法应该永远不被插件修改。
_setOptions
是一个通用的工具作为实例化后的设置options。它不应该被插件修改。
_setOption
通过option方法设置一个option值的时候被调用,也许这个方法在独立的插件中需要给修改,所以当某些选项修改是插件可以对应。比如title option修改是,title的内容应该更新。
_setOption: function(key, value) {
if (key === 'title') {
this.titleElement.text(value);
}
$.Widget.prototype._setOption.apply(this, arguments);
}
通过调用基本的_setOption方法,可以把option的值设为新值。这个不应该用_setOption设置。在某些实例中需要判断新值和旧值那一个是正确的。 在其他的一些实例中,你可以用 this.options[key]和你延迟的基本_setOption比较,直到结束。如果不需要比较,你可以在你的_setOption 上面调用基本的_setOption 。
enable
Helper方法调用option('disabled', false),你也许想通过在_setOption中的 if (key === "disabled")块来处理这个。
disable
Helper方法调用option('disabled', true),你也许想通过在_setOption中的 if (key === "disabled")块来处理这个。
_trigger
这个方法用来执行所有的callbacks。只需要回调函数的名称就可以执行了。所有的回调也触发事件(看上面的widgetEventPrefix ),你也许提供一个事件对象来代表事件的初始化处理。比如一个拖拽事件也许初始化一个鼠标移动的事件。所以原始的鼠标移动事件必须传递 到_trigger中。第三个参数是一个hash的数据传递到回调和事件处理函数。在hash中提供的数据应该具体事件和一些其他的不可读的插件api的信息。
Other Benefits and Use:
使用widget factory的插件仅仅处理插件的实例,不合被调用的jquery的方法一起使用。当你从一个jquery object上调用插件的一个方法。widget factory通过调用合适的插件实例来代理方法。它也会自动的处理链式,如果方法返回插件的实例,widget factory会在每一个插件对象上链式调用。如果返回的哦不是插件的实例,它会从原始的jqueyr对象上返回值。
引用
http://docs.jquery.com/Plugins/Authoring
http://xxh123.iteye.com/blog/1103545
http://wiki.jqueryui.com/w/page/12138135/Widget-factory
http://dingchao-lonton.iteye.com/blog/1402280
分享到:
相关推荐
“jQuery UI Cookbook” provides you with practical recipes featuring in-depth coverage of every widget in the framework, including how to address limitations that impact your everyday development ...
custom-jquerymobile-widget 基于jQuery Mobile的自定义窗口小部件类型 每个小部件的基本结构-jQuery UI Widget Factory
ParamQuery grid是一个轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Google Spreadsheet效果的网格。 使用ParamQuery...
ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Google Spreadsheet效果的网格。 使用ParamQuery,...
Tocify 是 Bootstrap 用来创建表格的插件。要求: jQuery 1.7.2 jQueryUI Widget Factory 1.8.21 支持浏览器:IE7 , Firefox 4 , Chrome, Safari 4 , and Opera 11 标签:Tocify
ParamQuery grid是一个轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Google Spreadsheet效果的网格。
jquery.imguruimageploader 基于 JQuery UI Widget Factory 的插件... script src =" js/vendor/jqueryui/jquery-ui.js " > </ script > < script src =" js/vendor/jqueryfileupload/jquery.iframe-trans
Tocify目前支持Twitter Bootstrap和jQueryUI Themeroller两种主题风格,我们可以根据实际项目任选其中一种风格,另外必要条件jQuery 1.7.2+和jQueryUI Widget Factory 1.8.21+。放心在IE7+即现代浏览器上使用。 ...
如果要使用小部件,则还需要jQuery和jQuery UI Widget Factory。 amplience-api.js不需要jQuery,并且可以通过Dynamic Imaging API(DI)处理资产数据的检索和处理。 [removed][removed] [removed][removed] <...
密码强度此JQuery插件有助于创建可抵御暴力攻击的强密码。 注意:此存储库包含两个版本的password_strength插件。... 如果您喜欢不使用Widget Factory且不依赖jQuery UI的简单实现,则应使用password_strength_lightwe
该插件是使用jQuery UI Widget Factory构建的。 欲了解更多信息,当前版本: 0.1特征自动调整大小的输入。 输入的整体外观,可进行直观的编辑。 存储用户为会话输入的所有值或永久存储的值。 Ajax将请求发送到...
ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能... 计算机视觉算法库Tracking.js394 Tracking.js 库给浏览器带来不同...
ParamQuery grid是一个轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能够在网页上展示各种类似于Excel和Google Spreadsheet效果的网格。 详细信息...
Advance your jQuery skills by learning about patterns such as divide and conquer, facade, and builder and factory to handle complex results This step-by-step guide to applying micro-patterns and ...
PrimeUI使用JSON数据,并使用jQuery UI的WidgetFactory API提供Widget控件,作为jQuery插件。其代码开源,采用Apache许可证。 PrimeUI最终发布的控件列表包括: - InputText - InputTextarea - SelectOneMenu - ...
ParamQuery是一种轻量级的jQuery网格插件,基于用于用户界面控制、具有一致API的优秀设计模式jQueryUI Widget factory创建,能... 计算机视觉算法库Tracking.js394 Tracking.js 库给浏览器带来不同...
3.$.widget //通过jQuery UI 部件工厂模式创建。 二、插件的开发过程 1.$.extend(); 这个方法其实很简单,只是像$上面添加了一个静态的方法而已。主要用途是对插件api的扩展. eg: //$.extend();为了防止,变量和...