这种插件架构使你可以在插件的父闭包中封装所有方法,调用时先传方法名称字符串,接下来再把你需要的其它参数传给该方法。这种封装和架构是 jQuery 插件社区的一个标准,已经被无数插件所使用,包括 jQueryUI
中的插件和小部件。
事件
bind
方法有个鲜为人知的特性:它支持为绑定事件定义名称空间。如果你的插件要绑定事件,最好为其定义名称空间。这样,回头想 unbind
的时候就不会影响到相同事件类型上的其它已绑定事件。要为事件定义名称空间,把 ".<namespace>" 附到要绑定的事件类型后面即可。
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
$(window).bind('resize.tooltip', methods.reposition);
});
},
destroy : function( ) {
return this.each(function(){
$(window).unbind('.tooltip');
})
},
reposition : function( ) {
// ...
},
show : function( ) {
// ...
},
hide : function( ) {
// ...
},
update : function( content ) {
// ...
}
};
$.fn.tooltip = function( method ) {
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 );
--
$('#fun').tooltip();
// Some time later...
$('#fun').tooltip('destroy');
在本例中,当 tooltip 被 init 方法初始化的时候,它把 reposition 方法绑定到 window 对象的 resize 事件上,名称空间为 "tooltip"。 之后,如果开发者想要销毁对象,可以把插件的名称空间(即 "tooltip")传给 unbind 方法,以便解除本插件对所有事件的绑定。这使得我们可以安全的地解除本插件的事件绑定,避免意外影响插件之外绑定的事件。
数据
插件开发中,你可能经常需要维护状态,或检查你的插件是否已在给定元素上做过初始化。jQuery data
方法是针对每个元素跟踪变量的好办法。不过最好能用单一对象容纳所有变量并用单一名称空间访问此对象,而不是分别跟踪一堆不同名字的数据。
(function( $ ){
var methods = {
init : function( options ) {
return this.each(function(){
var $this = $(this),
data = $this.data('tooltip'),
tooltip = $('<div />', {
text : $this.attr('title')
});
// If the plugin hasn't been initialized yet
if ( ! data ) {
/*
Do more setup stuff here
*/
$(this).data('tooltip', {
target : $this,
tooltip : tooltip
});
}
});
},
destroy : function( ) {
return this.each(function(){
var $this = $(this),
data = $this.data('tooltip');
// Namespacing FTW
$(window).unbind('.tooltip');
data.tooltip.remove();
$this.removeData('tooltip');
})
},
reposition : function( ) { // ... },
show : function( ) { // ... },
hide : function( ) { // ... },
update : function( content ) { // ...}
};
$.fn.tooltip = function( method ) {
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 );
data 方法可以帮你在插件的多次方法调用之间跟踪变量和状态。 把数据置于单一对象中,并为其定义名称空间有利于集中访问插件的所有属性,同时也减少了名称空间以便需要时删除。
总结及最佳实践
编写 jQuery 插件使库更加高效。把你最聪明、最有用的功能抽象成可重用代码,这将节省你的时间,进一步提高开发效率。下面是本文档的简要总结以及你开发下一个 jQuery 插件时的注意事项:
总是把插件包装在闭包中
{ /* plugin goes here */ })( jQuery );