Jquery系列文章之开发插件(11章)

   开发Jquery插件

   本章,我们简绍 几种不同插件的开发方法,有简单有复杂。首先,从添加新的全局函数的插件开始,然后再逐步讨论各种形式的jquery对象方法。此外,还将讨论以新表达式来扩展jquery选择符引擎,最后在简绍怎样把插件共享给其他开发人员。

 

 

11.1 添加新的全局函数

   所谓全局函数,就是jquery对象的方法,但从实践的角度来说,它们是位于jquery命名空间内部的函数。例如$.ajax()所作的一切可以通过名为ajax()的常规全局函数来实现,但这种方式(通过$或jquery直接调用方法名)会造成函数命名冲突的问题。解决方法名冲突的方法是,通过将函数放入jquery的不同命名空间中去。

   要向jquery命名空间中添加一个函数,只需要将这个函数指定为jquery对象的一个属性:

    

      

    于是我们就可以在使用这个插件的任何地方,编写如下代码使用它:

     jquery.globalFunction();

或通过别名$写成:

     $.globalFunction();

 

11.1.1 添加多个函数

    如果想在同一个js文件中提供多个全局函数,可以独立地声明它们:

   

 

 

调用它们:

   

 

 

还可以使用$.extend()函数使函数的定义更清晰:

    

以上代码会得到同样的结果。

 

 

   为避免方法名冲突,最好把属于一个插件的所有全局函数都封装到一个对象中去:

   

 

调用时如下:

   

 

 

11.1.2  插件实用方法

    核心的jquery库提供了许多全局函数都是实用方法。即这些方法为频繁执行任务提供了快捷方式。数组处理函数$.each()、$.map()、$.grep()都是这方面的例子。下面通过添加一个新的$.sum()方法,来示范如何创建这种实用方法。

 

    这个方法通过接受一个数组参数,并将数组中的值累加起来,返回结果。代码如下:

   

   

   为了测试方法,写一个页面,html内容如下:

  

   

接着在编写一段脚本,把返回值添加到标签array-sum上面去:

  

   

continuing...

 

11.2  添加jquery 对象方法

    jquery内置功能大部分都是通过其对象的方法提供的,而这些方法也是插件之所以诱人的关键。当函数需要操作DOM元素时,就是将函数创建为jquery对象方法的好机会。

     添加实例方法与添加全局方法类似,但扩展的是jquery.fn(jquery.prototype的别名)对象:

    jquery.fn.myMethod=function(){

    alter('Nothing happen!');

}

    然后就可以在使用任何选择符表达式之后调用这个方法了:

    $('div.myclassName').myMehtod();

 

    我们前面提到“当函数需要操作DOM元素时,就是将函数创建为jquery对象方法的好机会”,一个合理的实例方法应包含对它的环境的操作。

11.2.1 对象方法的环境

   在任何插件方法内部,关键字this引用的都是当前的jquery对象。因而,可以在this上面调用任何内置的jquery方法,或提取它包含的DOM节点并操作该节点:

   

 

    为了确定如何才能利用对象环境,下面我们来编写个小插件,用来操作匹配元素的类。

   

   为了测试这段代码是否有效,需要以下html:

   

    样式表css 如下:

   

方法swapClass中需要解释的几个地方:

  • 隐式迭代:要在匹配多个元素的情况下保证行为正确,最简单的方式就是始终在方法的环境上调用.each()方法,这就会执行隐式迭代,而隐式迭代对于维护插件与内置方法的一致性是至关重要的。
  • 方法连缀:在定义对象方法时,我们必须在所有插件方法中返回一个jquery对象(除非相应的方法明显用于取得不同的信息),以便于能够正常使用连缀行为。如下面所示:

 11.3 Dom遍历方法

   在某些情况下,我们定义的插件方法可能会改变jquery对象引用的DOM元素。

比如,我们想要添加一个查找匹配元素的祖父级元素的DOM遍历方法:

解释下这段代码:创建一个新的grandparents数组,并通过迭代将当前juqery对象引用的全部元素填充这个数组。然后调用.unique()方法去掉填充后的数组中重复的元素;最后,jquery内置的方法.setArray()把这组元素转换成新数组。

 

   为了测试这个方法,定义一个深度嵌套的<div>结构:

 

粗体标示目标元素(<div class="target">
)。使用我们定义的方法,就可以取得目标元素的祖父级的元素了。执行调用方法如下:

    然而,我们定义的grandparent方法是有破坏性的。因为调用方法作用是突出显示祖父级元素,然后再隐藏自身,而实际的效果是隐藏了祖父级别的元素,而非自身。

    为了避免这种情况,需要改变我们定义的方法,借助jquery在内部为每个对象维护的栈,可以做到这一点。

 

这样,$target就没有被修改,最初的目标对象将被代码隐藏起来。在调用此方法时,还可以连缀方法。如:

$(document).ready(function() {
    $('.target').grandparent().andSelf().addClass('highlight');
});

 

11.4  添加新的简写方法

    jquery库必须在方便和复杂之间维持一个微妙的平衡。添加到库中的每个方法都有助于开发者简化某些代码的编写,但也会增加基础代码的整体大小并可能影响性能。基于这点考虑,内置功能的许多简写方法都移交到插件中实现,以便开发者可以挑出对某个项目有用的方法,并省略那些无用的方法。

    当我们发现自己在代码中需要多次重复使用某个方法时,可能会想到为该方法创建一种简写的形式。如,假设我们利用内置的“滑动”和“淡化”技术频繁为页面元素添加动画效果。这两个效果放到一起意味着同时变换元素的高度和不透明度,而使用.animate()方法可以简化这两个操作。

   

   出于完整性考虑,我们的新方法也应该支持与内置的简写方法相同的参数。具体来说,应该像.fadeIn()方法一样那个自定义速度和回调函数。所以,可以进一步改写代码:

  

    这样,我们就有了与内置的简写方法具有类似功能的自定义的简写方法。为了演示这个方法,需要一个简单的html页面:

  

 

在按钮单击时,脚本会调用我们定义的新方法:

 

而效果也和我们想象的一样。

 

 

 

continuing...

 

11.5 方法的参数

    下面介绍几种管理方法参数的技巧。例子:为文本块添加投影添加插件方法。

文本块代码如下:

 

     要实现此文本块(标题)的投影效果,需要编写一小段代码(方法),实现的思路是:对于每个调用此方法的元素,都要复制该元素一定数量的副本,调整每个副本的不透明度,再通过绝对定位的方式,以原有元素为基准按照不同的偏移量定位这些副本。

     实现代码如下:

    

     调用此插件方法很简单:

 $(document).ready(function() {
   $('h1').shadow();
 });

 

11.5.1 为方法添加简单参数

   为了让用户使用此方法时,能够修改副本的相对位移、透明度等,我们需要把这些值定义为方法接受的参数列表。修改后的方法如下:

   调用此对象方法:

$(document).ready(function() {
   $('h1').shadow(10, 0.05, -2);
 });

    但这个对象方法还不够理想,这3个参数容易搞混,它们次序没有任何规则可循。

11.5.2 参数映射

    作为一种向用户公开选项的方式,映射显然要比参数列表更加友好。映射会为每个参数提供一个更有意义的标签,同时也让参数次序变得无关紧要,而且,只要有可能通过插件来模仿jquery API,就应该使用映射来提高一致性和易用性。

  

 调用这个方法需要传递一个值映射,而不是独立的各个参数了。

 $(document).ready(function() {
   $('h1').shadow({
     slices: 8,
     opacity: 0.1,
     zIndex: 1
   });
 });

   这样,只要扫一眼调用方法的代码,就知道每个参数的作用。

 

11.5.3  默认参数值

    随着参数的增多,在影射中始终指定每个参数不是必须的。此时,一组合理的默认值可以增强插件接口的易用性。

在这个方法中,我们定义了一个新的映射defaults,实用函数.extend()可以用接受的选项映射参数来覆盖defaults中的对应项,并保持选项映射中未指定的默认项不变。

 

   调用方法如下:

$(document).ready(function() {
    $('h1').shadow({
     opacity: 0.05 //仅修改透明度值,未指定的参数值为预先定义的默认项值
   });
});

 

$.extend()方法可以接受null值,在用户可以接受所有默认参数时,我们的方法可以直接执行而不会出错:

$(document).ready(function() {
    $('h1').shadow();

});

 

11.5.4  回调函数

    要在方法中使用回调函数,需要接受一个函数对象作为参数,然后在方法中适当的位置上调用该函数。例如:扩展前面定义的文本投影方法,让用户自定义投影相对于文本的位置。

投影的每个“切片”相对于原始文本都有不同的偏移量。现在,偏移量根据函数sliceOffset()计算出来,用户可以自定义此函数。调用此方法如下:

 $(document).ready(function() {
   $('h1').shadow({
     sliceOffset: function(i) {
       return {x: -i, y: -2*i};
     }//sliceOffset函数
   });//映射参数结束,投影方法结束
 });

 

11.5.5 可定制的默认值

   如果有脚本多次调用我们的插件,每次调用都要传递一组不同于默认值的参数,那么定制默认值就显得有必要,这样调用时可以减少很多的代码的编写。

   要支持默认值的可定制,需要把它们从方法定义中移出来,放到外部代码可以访问的地方:

 

    由于现在所有对.shadow()的调用都要重用defaults映射,因此不能让$.extend()修改它,我们在此定义一个空映射({})作为$.extend()第一个个参数,让这个新对象作为被修改的目标。

    于是,使用插件方法时就可以修改默认值了,修改之后的值可以被所有后续对.shadow()的调研共享,而且,在调用方法是仍然可以传递选项:

 

11.6  自定义选择符表达式

   jquery内置的组件也可以扩展,与添加新方法不同,我们可以自定义现有的组件。比如一个常见的需求就是自定义jquery提供的选择符表达式,以便得到更高级的选择符。

   最简单的选择符 表达式是伪类,即以冒号开头的表达式,如:checked/:nth-child()等。

   下面,我们自定义一个选择符表达式,:css()伪类,这个选择符表达式允许我们基于css属性的数字值查找元素。

 需要解释的如下:

  • 以上代码告诉jquery,css是一个可以在选择符表达式中前置冒号的有效字符串,当遇到该字符串时,应该调用给定的函数以确定当前元素是否应该包含在结果集中。
  • element:当前的DOM元素。大多数选择符都需要这个参数。
  • index:DOM元素在结果集中的索引。这个参数对:eq()和:lt()等选择符有用。
  • matches:包含解析当前选择符的正则表达式结果的数组。通常matches[3]是 这个数组中唯一有用的项。
  • set:到目前为止匹配的整个DOM元素集合。很少用。

    我们可以通过一下文档演示它的用途:

使用新的选择符表达式,突出显示里表中文本较短的项就很容易了:

$(function() {
    $('div:css(width < 100)').addClass('highlight');
});

 

 

参考《jquery基础教程》第二版

猜你喜欢

转载自blog.csdn.net/manbufenglin/article/details/5017350