我们已经知道this指代jQuery选择器返回的集合,那么通过调用jQuery的.each()方法就可以处理合集中的每个元素了,但此刻要注意的是在each方法内部,this指带的是普通的DOM元素了,如果需要调用jQuery的方法,那就需要用$来重新包装一下。
比如现在我们要在每个链接处显示链接的真实地址,首先通过each遍历所有a标签,然后获取href属性的值,再加到链接文本后面。
更改后我们的插件代码为:
$.fn.myPlugin = function(){ this.css('color','red'); this.each(function(){ $(this).append(' ' + $(this).attr('href')); }); };
运行结果:
到此,你已经可以编写功能简单的jQuery插件了,是不是也没那么难。
下面开始jQuery插件编写中一个重要的部分,参数的接收。
支持链式调用我们都知道jQuery一个非常优雅的特性是支持链式调用,选择好DOM元素后可以不断地调用其他方法。
要让插件不打破这种链式调用,只需return一下即可。
$.fn.myPlugin = function(){ this.css('color','red'); return this.each(function(){ $(this).append(' ' + $(this).attr('href')); }); };
让插件接收参数一个强劲的插件是可以让使用者随意定制的,这要求我们提供在编写插件时就要考虑得全面些,尽量提供合适的参数。
比如现在我们不想让链接只变成红色,我们让插件的使用者自己定义显示什么颜色,要
做到这一点很方便,只需要使用者在调用的时候传入一个参数即可。同时我们在插件的代码里面接收。另一方面,为了灵活,使用者可以不传递参数,插件里面会给出参数的默认值。
在处理插件参数的接收上,通常使用jQuery的extend方法,上面也提到过,但那是给extend方法传递单个对象的情况下,这个对象会合并到jQuery身上,所以我们就可以在jQuery身上调用新合并对象里包含的方法了,像上面的例子。当给extend方法传递一个以上的参数时,它会将所有参数对象合并到第一个里。同时,如果对象中有同名属性时,合并的时候后面的会覆盖前面的。
利用这一点,我们可以在插件里定义一个保存插件参数默认值的对象,同时将接收来的参数对象合并到默认对象上,最后就实现了用户指定了值的参数使用指定的值,未指定的参数使用插件默认值。
为了演示方便,再指定一个参数fontSize,允许调用插件的时候设置字体大小。
$.fn.myPlugin = function(options){ var defaults={ 'color' : 'red', 'fontSize' : '12px' }; var settings=$.extend(defaults,options); return this.css({ 'color' : settings.color, 'fontSize' : settings.fontSize }); };
现在,我们调用的时候指定颜色,字体大小未指定,会运用插件里的默认值12px。
调用代码:
$('a').myPlugin({ 'color': '#2C9929' });
运行结果:
同时指定颜色与字体大小
$('a').myPlugin({ 'color': '#2C9929', 'fontSize': '30px' });
运行结果:
保护好默认参数注意到上面代码调用extend时会将defaults的值改变,这样不好,因为它作为插件因有的一些东西应该维持原样,另外就是如果你在后续代码中还要使用这些默认值的话,当你再次访问它时它已经被用户传进来的参数更改了。
一个好的做法是将一个新的空对象做为$.extend的第一个参数,defaults和用户传递的参数对象紧随其后,这样做的好处是所有值被合并到这个空对象上,保护了插件里面的默认值。
如下代码:
$.fn.myPlugin = function(options){ var defaults={ 'color' : 'red', 'fontSize' : '14px' }; var settings=$.extend({},defaults,options); return this.css({ 'color' : settings.color, 'fontSize' : settings.fontSize }); };
到此,插件可以接收和处理参数后,就可以编写出更健壮而灵活的插件了。若要编写一个复杂的插件,代码量会很大,如何组织代码就成了一个需要面对的问题。没有一个好的方式来组织这些代码,整体代码就会感觉杂乱无章,同时也不好维护,所以将插件的所有方法属性包装到一个对象上,用面向对象的思维来进行开发,无疑会使工作轻松很多。
到此先介绍到这里,下一节将介绍“面向对象的插件开发”!