jQuery插件的开发包括两种:
一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法。jQuery的全局函数就是属于jQuery命名空间的函数;
另一种是对象级别的插件开发,即给jQuery对象添加方法。下面就两种函数的开发做详细的说明。
第一种:类级别的插件开发
类级别的插件开发最直接的理解就是给jQuery类添加类方法,可以理解为添加静态方法。典型的例子就是$.AJAX()这个函数,将函数定义于jQuery的命名空间中。关于类级别的插件开发可以采用如下几种形式进行扩展:
1、添加一个或多个新的全局函数,我们只需如下定义:
jQuery.foo = function() {
alert('This is a test. This is only a test.');
};
jQuery.bar = function(param) {
alert('This function takes a parameter, which is "' + param + '".');
};
调用时和一个函数的一样的:jQuery.foo();jQuery.bar();或者$.foo();$.bar('bar');
2、使用jQuery.extend(object);
jQuery.extend({
foo: function() {
alert('This is a test. This is only a test.');
},
bar: function(param) {
alert('This function takes a parameter, which is "' + param +'".');
}
});
第二种:对象级别的插件开发
对象级别的插件开发需要如下的两种形式:
形式1:
( function( $ ) {
$.fn.extend( {
pluginName: function( opt, callback ) {
// Our plugin implementation code goes here.
}
} )
} )( jQuery );
形式2:
( function( $ ) {
$.fn.pluginName = function() {
// Our plugin implementation code goes here.
};
} )( jQuery );
上面定义了一个jQuery函数,形参是$,函数定义完成之后,把jQuery这个实参传递进去.立即调用执行。这样的好处是,我们在写jQuery插件时,也可以使用$这个别名,而不会与prototype引起冲突.。
步骤:
在JQuery名称空间下申明一个名字
这是一个单一插件的脚本。如果你的脚本中包含多个插件,或者互逆的插件(例如: $.fn.doSomething() 和$.fn.undoSomething()),那么你需要声明多个函数名字。但是,通常当我们编写一个插件时,力求仅使用一个名字来包含它的所有内容。我们的示例插件命名为“highlight“
$.fn.hilight = function() {
// Our plugin implementation code goes here.
};
我们的插件通过这样被调用:
$('#myDiv').hilight();
但是如果我们需要分解我们的实现代码为多个函数该怎么办?有很多原因:设计上的需要;这样做更容易或更易读的实现;而且这样更符合面向对象。 这真是一个麻烦事,把功能实现分解成多个函数而不增加多余的命名空间。出于认识到和利用函数是javascript中最基本的类对象,我们可以这样做。就像其他对象一样,函数可以被指定为属性。因此我们已经声明“hilight”为jQuery的属性对象,任何其他的属性或者函数我们需要暴露出来的,都可以在"hilight" 函数中被声明属性。稍后继续。
接受options参数以控制插件的行为
让我们为我们的插件添加功能指定前景色和背景色的功能。我们也许会让选项像一个options对象传递给插件函数。例如:
// plugin definition
$.fn.hilight = function( options ) {
var defaults = {
foreground: 'red',
background: 'yellow'
};
// Extend our default options with those provided.
var opts = $.extend( defaults, options );
// Our plugin implementation code goes here.
};
我们的插件可以这样被调用:
$('#myDiv').hilight({
foreground: 'blue'
});
<span style="background-color: rgb(247, 252, 255); font-family: Arial, Tahoma, Verdana, sans-serif;">
</span>
<span style="background-color: rgb(247, 252, 255); font-family: Arial, Tahoma, Verdana, sans-serif;"><em><strong> 暴露插件的默认设置 </strong></em></span>
我们应该对上面代码的一种改进是暴露插件的默认设置。这对于让插件的使用者更容易用较少的代码覆盖和修改插件。接下来我们开始利用函数对象。
// plugin definition
$.fn.hilight = function( options ) {
// Extend our default options with those provided.
// Note that the first arg to extend is an empty object -
// this is to keep from overriding our "defaults" object.
var opts = $.extend( { }, $.fn.hilight.defaults, options );
// Our plugin implementation code goes here.
};
// plugin defaults - added as a property on our plugin function
$.fn.hilight.defaults = {
foreground: 'red',
background: 'yellow'
};
现在使用者可以包含像这样的一行在他们的脚本里:
//这个只需要调用一次,且不一定要在ready块中调用
$.fn.hilight.defaults.foreground = 'blue';
接下来我们可以像这样使用插件的方法,结果它设置蓝色的前景色:
$('#myDiv').hilight();
如你所见,我们允许使用者写一行代码在插件的默认前景色。而且使用者仍然在需要的时候可以有选择的覆盖这些新的默认值:
// 覆盖插件缺省的背景颜色
$.fn.hilight.defaults.foreground = 'blue';
// ...
// 使用一个新的缺省设置调用插件
$('.hilightDiv').hilight();
// ...
// 通过传递配置参数给插件方法来覆盖缺省设置
$('#green').hilight({
foreground: 'green'
});
适当的暴露一些函数
这段将会一步一步对前面那段代码通过有意思的方法扩展你的插件(同时让其他人扩展你的插件)。例如,我们插件的实现里面可以定义一个名叫"format"的函数来格式化高亮文本。我们的插件现在看起来像这样,默认的format方法的实现部分在hiligth函数下面。
// plugin definition
$.fn.hilight = function( options ) {
// iterate and reformat each matched element
return this.each( function() {
var $this = $( this );
// ...
var markup = $this.html();
// call our format function
markup = $.fn.hilight.format( markup );
$this.html( markup );
} );
};
// define our format function
$.fn.hilight.format = function( txt ) {
return '<strong>' + txt + '</strong>';
};
保持私有函数的私有性
这种技巧暴露你插件一部分来被覆盖是非常强大的。但是你需要仔细思考你实现中暴露的部分。一但被暴露,你需要在头脑中保持任何对于参数或者语义的改动也许会破坏向后的兼容性。一个通理是,如果你不能肯定是否暴露特定的函数,那么你也许不需要那样做。
那么我们怎么定义更多的函数而不搅乱命名空间也不暴露实现呢?这就是闭包的功能。为了演示,我们将会添加另外一个“debug”函数到我们的插件中。这个 debug函数将为输出被选中的元素格式到firebug控制台。为了创建一个闭包,我们将包装整个插件定义在一个函数中。
( function( $ ) {
// plugin definition
$.fn.hilight = function( options ) {
debug( this );
// ...
};
// private function for debugging
function debug( $obj ) {
if ( window.console && window.console.log )
window.console.log( 'hilight selection count: ' + $obj.size() );
}
;
// ...
} )( jQuery );
我们的“debug”方法不能从外部闭包进入,因此对于我们的实现是私有的。
整合
下面使我们的例子完成后的代码:
// 创建一个闭包
( function( $ ) {
// 插件的定义
$.fn.hilight = function( options ) {
debug( this );
// build main options before element iteration
var opts = $.extend( { }, $.fn.hilight.defaults, options );
// iterate and reformat each matched element
return this.each( function() {
$this = $( this );
// build element specific options
var o = $.meta ? $.extend( { }, opts, $this.data() ) : opts;
// update element styles
$this.css( {
backgroundColor: o.background,
color: o.foreground
} );
var markup = $this.html();
// call our format function
markup = $.fn.hilight.format( markup );
$this.html( markup );
} );
};
// 私有函数:debugging
function debug( $obj ) {
if ( window.console && window.console.log )
window.console.log( 'hilight selection count: ' + $obj.size() );
}
;
// 定义暴露format函数
$.fn.hilight.format = function( txt ) {
return '<strong>' + txt + '</strong>';
};
// 插件的defaults
$.fn.hilight.defaults = {
foreground: 'red',
background: 'yellow'
};
// 闭包结束
} )( jQuery );
这段设计已经让我创建了强大符合规范的插件。我希望它能让你也能做到。