在编写jQuery插件时,必须假设jQuery库已经加载到了页面中。可是,我们不能假设$别名一定可用。也有与$别名产生冲突的时候。
对于代码比较长的插件来说,很多开发人员都觉得不能使用$别名会导致代码难以理解。为了解决这个问题,我们可以在插件的作用域内定义这个快捷方式,方法就是定义一个函数并马上调用它。这种定义并立即调用函数的语法通常被称为立即调用的函数表达式(IIFE,Immediately Invoked Function Expression):
(function($) {//在这里添加代码
})(jQuery);
这个包装函数只接收一个参数,我们通过这个参数传入了jQuery对象。这个参数的名字是$,因此在这个函数内部,使用$别名就不会有冲突了。
jQuery内置的某些功能是通过全局函数提供的。所谓全局函数,实际上就是jQuery对象的方法,但从实践的角度上看,它们是位于jQuery命名空间内部的函数。
使用这种技术的一个典型的例子就是$.ajax()函数。$.ajax()所做的一切都可以通过简
单地调用一个名为ajax()的常规全局函数来实现,但是,这种方式会给我们带来函数名冲突的问题。通过把这个函数放在jQuery的命名空间内,我们只需避免它与其他的jQuery方法冲突即可。对想要使用插件的人而言,jQuery命名空间也是一个提醒,即要使用这个插件,必须要有jQuery库。
核心jQuery库提供的很多全局函数都是实用方法;所谓实用方法,就是一些常用功能的快捷方式,但即使手工编写同样功能的代码也不是很难。数组处理方法$.each()、$.map()和$.grep()都是实用方法。为了演示这些实用方法的创建方式,我们再给jQuery核心库添加两个小函数。
要向jQuery的命名空间中添加函数,只需将这个新函数指定为jQuery对象的一个属性即可。
(function($) { $.sum = function(array) {
//在这里添加代码};
})(jQuery);
于是,我们就可以在使用这个插件的任何代码中,编写如下代码:
$.sum();
这跟一个基本的调用没什么两样,调用之后就会执行函数体内的代码。
这个求和函数接受一个数组作为参数,然后把数组的值加在一起,最后返回结果。代码如下:
(function($) {
$.sum = function(array) {
var total = 0;
$.each(array, function(index, value) {
value = $.trim(value);
value =parseFloat(value) || 0;
total += value;
});
return total;
};
})(jQuery);
注意,我们在这里使用了$.each()方法遍历了数组的值。当然也可以在此使用for循环,但既然我们能够确定页面会在加载插件之前先加载jQuery库,使用习以为常的语法是很自然的。同样,$.each()的好处在于它的第一个参数是一个对象。
我们的插件在jQuery命名空间中创建了两个独立的全局函数。但这样写有可能污染命名空间。换句话说,其他jQuery插件也可能定义相同的函数名。为了避免冲突,最好的办法是把属于一个插件的全局函数都封装到一个对象中,代码如下所示:
(function($) {
$.mathUtils = {
sum: function(array) {
var total = 0;
$.each(array, function(index, value) {
value = $.trim(value);
value = parseFloat(value) || 0;
total += value;
});
return total;
},
average: function(array) {
if ($.isArray(array)) {
return $.mathUtils.sum(array) / array.length;
}
return '';
}
};
}) (jQuery);
这个模式的本质是为所有的全局函数又创建了一个命名空间,叫做jQuery.mathUtils。虽然我们还称它们为全局函数,但实际上它们已经成了mathUtils对象的方法了,而mathUtils对象则保存在jQuery对象的属性中。结果,在调用它们时就必须得加上插件的名字了:
$.mathUtils.sum(sum);
$.mathUtils.average(average);
使用这种技术(以及足够独特的命名空间),就能够避免全局函数污染命名空间。至此,我们已经掌握了开发插件的基本方法。在把这些函数保存到名为jquery.mathutils.js的文件中之后,就可以将其包含在其他页面中通过其他脚本来使用这些函数了。
jQuery中大多数内置的功能都是通过其对象实例的方法提供的,而且这些方法也是插件之所以诱人的关键。当函数需要操作DOM元素时,就是将函数创建为jQuery实例方法的好机会。
前面我们已经看到,添加全局函数需要以新方法来扩展jQuery对象。添加实例方法也与此类似,但扩展的却是jQuery.fn对象:
jQuery.fn.myMethod = function() {
alert('Nothing happens.');
};
然后,就可以在使用任何选择符表达式之后调用这个新方法了:
$('div').myMethod();
当调用这个方法时会弹出一个警告框。由于这里并没有在任何地方用到匹配的DOM节点,所以为此编写一个全局函数也是一样的。由此可见,一个合理的实例方法应该包含对它的上下文的操作。
未完待续(_)