jquery插件开发
在软件开发过程中需要一定的设计模式来指导开发,有了模式,我们便能更好的组织我们的代码,并从前人的经验中学到更好的实践。
根据《jQuery高级编程》中的描述,jQuery插件开发方式重要有三种:
- 通过$.extend()来扩展jQuery
- 通过$.fn向jQuery添加新的方法
- 通过$.widget()应用jQuery UI的部件工厂方式创建(这种方式暂时很少用,估计你们也很少见吧!呵呵……)
通常我们使用第二种方法来进行简单的插件开发,说简单是相对于第三种方式。第三种方式是用来开发更高级的jQuery部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态信息自动保存,各种关于插件的方法等,都非常的细致。
而第一种方法又太简单,仅仅是在jQuery命名空间或者可以理解在jQuery自身添加一个静态的方法而已。所以我们在调用通过$.extend()添加的方法时,直接通过$符号调用$.myFunction()而不需要选中DOM元素$().myFunction()。
方式一、$.extend()
//定义插件
$.extend({
goTop:function(){
$('html,body').animate({scrollTop:0}, 500);
}
});
//调用
$('.gotop').click(function(){
$.goTop();
});
上面的代码中通过$.extend()方法向jQuery添加了一个goTop方法,然后通过$直接调用。到此已完成了一个简单的jQuery插件。
如你所见,通过此种方法来定义一些辅助类的方法是比较方便的,定义一次后,可以通过jQuery在程序中任何需要的地方调用它。
方式二、$.fn
第一种种方法,并不能使用jQuery强大的选择器,要处理DOM元素以及将开发的插件运用到所选的元素上,还是要使用第二种方法。我所见到和使用的插件大多也是通过$.fn的方式创建的,至少目前是。
第二种方式的语法示例:
$.fn.mypluginName = function(){
//代码内容
}
往$.fn上面添加一个方法,名字是我们插件的名称,然后我们的插件代码在这个方法中展开。
比如我们将页面中某元素背景颜色改为红色,则写成:
//定义插件
$.fn.pluginBg = function(){
this.css('backgroundColor','red'); //在这里,this指用jQuery选中的元素,即:this = $(element),this用法再此不过多介绍
}
//调用
$(elment).pluginBg();
传参插件
一个强劲的插件是可以让使用者随意定制的,这便要求我们在开发插件是考虑的更加全面些,尽量提供合适的参数。在处理插件参数的接收上,通常使用jQuery的extend方法,上面也有提到过,但那是给extend方法传递单个对象的情况下,这个对象会合并到jQuery身上,所以我们就可以在jQuery身上调用新合并对象里包含的方法了。当给extend方法传递多个对象时,它会将所有参数对象合并到第一个里。同时,如果对象中存在同名的属性,合并时后面的会覆盖前面的。利用这一点,我们可以在插件中定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了值得参数使用指定值,未指定参数时使用插件的默认值。
我们举个例子,允许用户调用插件的时候设置color,代码如下:
//定义插件
$.fn.pluginStyle = function(opt){
var defaults = {
'color' : 'red',
};
var settings = $.extend(defaults,opt);
return this.css({
'color': settings.color,
})
}
//不传参调用,则color设置为默认值red
$(elm).pluginStyle();
//传参调用,则color设置为blue
$(elm).pluginStyle({'color':'blue'});
到此,插件可以接收和处理参数后,就可以编写出更灵活的插件了。
面向对象插件
问:
若要编写一个复杂的插件,代码量会很大,如何组织代码就成了一个需要面临的问题,没有一个好的方式来组织代码,整体感觉会杂乱无章,同时也难以维护,怎么办呢?
答:
我们将插件的所有属性包装到一个对象上,用面向对象的思维来进行开发,那么,一切将迎刃而解!
我们将上面的例子美化一下,代码如下:
//定义Nick对象的构造方法
var Nick = function(ele, opt){
this.$element = ele,
this.defaults = {
'color': 'red'
},
this.options = $.extend(this.defaults,opt);
}
//定义对象的方法
Nick.prototype = {
handsome:function(){
return this.$element.css({
'color': this.options.color
});
}
}
//在插件中使用对象
$.fn.myPlugin = function(options){
//创建实体
var me = new Nick(this, options);
//调用其方法
return me.handsome();
}
//不传参调用,则color设置为默认值red
$(elm).pluginStyle();
//传参调用,则color设置为blue
$(elm).pluginStyle({'color':'blue'});
写到这里我感觉已经完美了,但是在吃饭完后准备发布的时候,看了看--哎呀!好像还有进步空间吖!
匿名函数的用处到了
不仅是jQuery插件的开发,我们在写任何JS代码的时都应该注意不要污染全局命名空间,因为随着代码量的增加,如果有意无意在全局范围内定义一些变量的话,最后很难维护,也会和别人写的代码发生冲突。
一个好的做法是始终使用自调用匿名函数包裹你的代码,这样就可以完全安全、放心的用到任何地方,绝对不会发生冲突问题。
在Javascript中无法使用花括号方便的创建作用域,但函数却可以形成一个作用域,域内的代码是无法被外界访问的,如果我们将自己的代码放入到函数中,那么就不会污染全局命名空间,同时也不会和别的代码发生冲突。所以我们将所有代码用自调用匿名函数包裹。
最后的将上面的插件代码用一个匿名函数包裹起来,大功告成!
结束时,还是那句话--望大神指教鞭策我!
补充 $.extend()
这里多谢某童鞋的提醒!说方式一还还可用于合并参数和深clone,虽然方式二中用了方式一做参数合并,但并未详细介绍,所以今天在此处做点补充!