首页 > 代码库 > jquery编写插件的方法

jquery编写插件的方法

   开发Jquery插件

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

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

 

 

11.1 添加新的全局函数

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

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

    

[javascript] view plaincopy
  1. jQuery.globalFunction = function() {  
  2.             alert(‘this is a test. Only a test.‘);  
  3.         };  

 

      

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

     jquery.globalFunction();

或通过别名$写成:

     $.globalFunction();

 

11.1.1 添加多个函数

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

   

[javascript] view plaincopy
  1. jQuery.functionOne = function() {  
  2.     return alert(‘function first!‘);  
  3. };  
  4.   
  5. jQuery.functionTwo = function() {  
  6.     return alert(‘function second!‘);  
  7. };  
  8. jQuery.functionThree = function() {  
  9.     return alert(‘function third!‘);  
  10. };  

 

 

 

调用它们:

   

[javascript] view plaincopy
  1. $.functionOne();  
  2. $.functionTwo();  
  3. $.functionThree();  

 

 

 

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

    

[javascript] view plaincopy
  1. jQuery.extend({  
  2.     functionOne: function() {  
  3.         return alert(‘function first!‘);  
  4.     },  
  5.   
  6.     functionTwo: function() {  
  7.         return alert(‘function second!‘);  
  8.     },  
  9.     functionThree: function() {  
  10.         return alert(‘function third!‘);  
  11.     }  
  12. });  

 

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

 

 

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

   

[javascript] view plaincopy
  1. jQuery.myPluginName = {  
  2.     functionOne: function() {  
  3.         return alert(‘function first!‘);  
  4.     },  
  5.   
  6.     functionTwo: function() {  
  7.         return alert(‘function second!‘);  
  8.     },  
  9.     functionThree: function() {  
  10.         return alert(‘function third!‘);  
  11.     }  
  12. };  

 

 

调用时如下:

   

[javascript] view plaincopy
  1. $.myPluginName.functionOne();  
  2. $.myPluginName.functionTwo();  
  3. $.myPluginName.functionThree();  

 

 

 

11.1.2  插件实用方法

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

 

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

   

[javascript] view plaincopy
  1. jQuery.sum = function(array) {  
  2.   var total = 0;  
  3.     
  4.   jQuery.each(array, function(index, value) {  
  5.     total += value;  
  6.   });  
  7.     
  8.   return total;  
  9. };  

 

   

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

  

[javascript] view plaincopy
  1. <body>    
  2.    <p>Array contents:</p>  
  3.    <ul id="array-contents"></ul>  
  4.    <p>Array sum:</p>  
  5.    <div id="array-sum"></div>  
  6.  </body>  

 

   

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

  

[javascript] view plaincopy
  1. $(document).ready(function() {  
  2.   var myArray = [52, 97, 0.5, -22];  
  3.     
  4.   $.each(myArray, function(index, value) {  
  5.     $(‘#array-contents‘).append(‘<li>‘ + value + ‘</li>‘);  
  6.   });  
  7.     
  8.   $(‘#array-sum‘).append($.sum(myArray));  
  9. });  

 

   

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节点并操作该节点:

   

[javascript] view plaincopy
  1. jQuery.fn.showAlter = function() {  
  2.     alter(‘You selected ‘+this.length+‘ elements.‘);  
  3. };  

 

 

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

   

[javascript] view plaincopy
  1. jQuery.fn.swapClass = function(class1, class2) {  
  2.   return this.each(function() { //this引用的是一个jquery对象  
  3.     var $element = jQuery(this);//this引用的是一个DOM元素  
  4.     if ($element.hasClass(class1)) {  
  5.       $element.removeClass(class1).addClass(class2);  
  6.     }  
  7.     else if ($element.hasClass(class2)) {  
  8.       $element.removeClass(class2).addClass(class1);  
  9.     }  
  10.   });  
  11. };  

 

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

   

[xhtml] view plaincopy
  1. <body>    
  2.     <ul>  
  3.       <li>Lorem ipsum dolor sit amet</li>  
  4.       <li class="this">Consectetur adipisicing elit</li>  
  5.       <li>Sed do eiusmod tempor incididunt ut labore</li>  
  6.       <li class="that">Magna aliqua</li>  
  7.       <li class="this">Ut enim ad minim veniam</li>  
  8.       <li>Quis nostrud exercitation ullamco</li>  
  9.       <li>Laboris nisi ut aliquip ex ea commodo</li>  
  10.       <li class="that">Duis aute irure dolor</li>  
  11.     </ul>  
  12.     <input type="button" value=http://www.mamicode.com/"Swap classes" id="swap" />  
  13.   </body>  

 

    样式表css 如下:

   

[css] view plaincopy
  1. body {   
  2.   font: 62.5% Arial, Verdana, sans-serif;   
  3. }   
  4.   
  5. ul {  
  6.   margin: 1em 0;  
  7.   padding: 0;  
  8. }  
  9. li {  
  10.   font-size: 1.1em;  
  11.   margin: 0.2em 1em;  
  12.   padding: 0;  
  13. }  
  14. .this {  
  15.   font-weight: bold;  
  16. }  
  17. .that {  
  18.   font-style: italic;  
  19. }  

 

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

  • 隐式迭代:要在匹配多个元素的情况下保证行为正确,最简单的方式就是始终在方法的环境上调用.each()方法,这就会执行隐式迭代,而隐式迭代对于维护插件与内置方法的一致性是至关重要的。
  • 方法连缀:在定义对象方法时,我们必须在所有插件方法中返回一个jquery对象(除非相应的方法明显用于取得不同的信息),以便于能够正常使用连缀行为。如下面所示:
    [javascript] view plaincopy
    1. $(document).ready(function() {  
    2.   $(‘#swap‘).click(function() {  
    3.     $(‘li‘)  
    4.       .swapClass(‘this‘, ‘that‘)  
    5.       .css(‘text-decoration‘, ‘underline‘);//连缀方法  
    6.     return false;  
    7.   });  
    8. });  

 11.3 Dom遍历方法

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

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

[javascript] view plaincopy
  1. jQuery.fn.grandparent = function() {  
  2.     var grandparents = [];  
  3.     this.each(function() {  
  4.         grandparents.push(this.parentNode.parentNode);  
  5.     });  
  6.     grandparents = jQuery.unique(grandparents);  
  7.     return this.setArray(grandparents);  
  8. };  

 

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

 

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

[xhtml] view plaincopy
  1. <div>  
  2.         Deserunt mollit anim id est laborum</div>  
  3.     <div>  
  4.         Ut enim ad minim veniam  
  5.         <div>  
  6.             Quis nostrud exercitation  
  7.             <div>  
  8.                 Ullamco laboris nisi  
  9.                 <div>  
  10.                     Ut aliquip ex ea</div>  
  11.                 <div class="target">  
  12.                     Commodo consequat  
  13.                     <div>  
  14.                         Lorem ipsum dolor sit amet</div>  
  15.                 </div>  
  16.             </div>  
  17.             <div>  
  18.                 Duis aute irure dolor</div>  
  19.             <div>  
  20.                 In reprehenderit  
  21.                 <div>  
  22.                     In voluptate</div>  
  23.                 <div>  
  24.                     Velit esse  
  25.                     <div>  
  26.                         Cillum dolore</div>  
  27.                     <div class="target">  
  28.                         Fugiat nulla pariatur</div>  
  29.                 </div>  
  30.                 <div>  
  31.                     Excepteur sint occaecat cupidatat</div>  
  32.             </div>  
  33.         </div>  
  34.         <div>  
  35.             Non proident</div>  
  36.     </div>  
  37.     <div>  
  38.         Sunt in culpa qui officia</div>  

 

 

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

[javascript] view plaincopy
  1. $(document).ready(function() {  
  2.   var $target = $(‘.target‘);  
  3.   $target.grandparent().addClass(‘highlight‘);  
  4.   $target.hide();  
  5. });  

 

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

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

[javascript] view plaincopy
  1. jQuery.fn.grandparent = function() {  
  2.     var grandparents = [];  
  3.     this.each(function() {  
  4.         grandparents.push(this.parentNode.parentNode);  
  5.     });  
  6.     grandparents = jQuery.unique(grandparents);  
  7.     return this.pushStack(grandparents);//会创建一个新jquery对象,而非修改原有对象  
  8. };  

 

 

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

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

 

11.4  添加新的简写方法

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

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

   

[javascript] view plaincopy
  1. jQuery.fn.slideFadeOut = function() {  
  2.     return this.animate({  
  3.         height: ‘hide‘,  
  4.         opacity: ‘hide‘  
  5.     });  
  6. };  
  7.   
  8. //淡入  
  9. jQuery.fn.slideFadeIn = function() {  
  10.     return this.animate({  
  11.         height: ‘show‘,  
  12.         opacity: ‘show‘  
  13.     });  
  14. };  
  15.   
  16. //折叠(淡入、淡出)  
  17. jQuery.fn.slideFadeToggle = function() {  
  18.     return this.animate({  
  19.         height: ‘toggle‘,  
  20.         opacity: ‘toggle‘  
  21.     });  
  22.   
  23. };  

 

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

  

[javascript] view plaincopy
  1. jQuery.fn.slideFadeOut = function(speed, callback) {  
  2.     return this.animate({  
  3.         height: ‘hide‘,  
  4.         opacity: ‘hide‘  
  5.     }, speed, callback);  
  6. };  
  7.   
  8. jQuery.fn.slideFadeIn = function(speed, callback) {  
  9.     return this.animate({  
  10.         height: ‘show‘,  
  11.         opacity: ‘show‘  
  12.     }, speed, callback);  
  13. };  
  14.   
  15. jQuery.fn.slideFadeToggle = function(speed, callback) {  
  16.     return this.animate({  
  17.         height: ‘toggle‘,  
  18.         opacity: ‘toggle‘  
  19.     }, speed, callback);  
  20. };  

 

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

  

[javascript] view plaincopy
  1. <div>  
  2.         <p>  
  3.             Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor  
  4.             incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud  
  5.             exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute  
  6.             irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla  
  7.             pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia  
  8.             deserunt mollit anim id est laborum.</p>  
  9.         <div class="controls">  
  10.             <asp:Button ID="out" runat="server" Text="Slide and fade out" />  
  11.             <%--<input type="button" value=http://www.mamicode.com/"Slide and fade out" id="out" />--%>  
  12.             <input type="button" value=http://www.mamicode.com/"Slide and fade in" id="in" />  
  13.             <input type="button" value=http://www.mamicode.com/"Toggle" id="toggle" />  
  14.         </div>  

 

 

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

[javascript] view plaincopy
  1. /// <reference path="../../scripts/jquery-1.3.2-vsdoc2.js" />  
  2. /// <reference path="jquery.solidFade.js" />  
  3. $(function() {  
  4.     $(‘#out‘).click(function() {  
  5.         $(‘p‘).slideFadeOut(‘slow‘);  
  6.         return false;  
  7.     });  
  8.     $(‘#in‘).click(function() {  
  9.         $(‘p‘).slideFadeIn(‘slow‘);  
  10.         return false;  
  11.     });  
  12.     $(‘#toggle‘).click(function() {  
  13.         $(‘p‘).slideFadeToggle(‘slow‘);  
  14.         return false;  
  15.     });  
  16. });  

 

 

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

 

 

 

continuing...

 

11.5 方法的参数

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

文本块代码如下:

[xhtml] view plaincopy
  1. <body>  
  2.     <h1>  
  3.         The quick brown fox jumps over the lazy dog.</h1>  
  4. </body>  

 

 

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

     实现代码如下:

    

[javascript] view plaincopy
  1. jQuery.fn.shadow = function() {  
  2.     return this.each(function() {  
  3.         var $originalElement = $(this);  
  4.         for (var i = 0; i < 5; i++) {  
  5.             $originalElement  
  6.             .clone()  
  7.             .css({  
  8.                 position: ‘absolute‘,//绝对定位方式,让每个副本基于上一个元素按照不同的偏移量定位  
  9.                 left: $originalElement.offset().left + i,  
  10.                 top: $originalElement.offset().top + i,  
  11.                 margin: 0,  
  12.                 zIndex: -1,  
  13.                 opacity: 0.1  
  14.             })  
  15.             .appendTo(‘body‘); //加入到body标签中  
  16.         }  
  17.     });  
  18. };  

 

     调用此插件方法很简单:

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

 

11.5.1 为方法添加简单参数

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

[javascript] view plaincopy
  1. //step2(接受3个参数。缺点:参数不太明确,易搞混)  
  2. jQuery.fn.shadow = function(slice, opacity, zIndex) {  
  3.     return this.each(function() {  
  4.         var $originalElement = $(this);  
  5.         for (var i = 0; i < slice; i++) {  
  6.             $originalElement  
  7.             .clone()  
  8.             .css({  
  9.                 position: ‘absolute‘, //绝对定位方式,让每个副本基于上一个元素按照不同的偏移量定位  
  10.                 left: $originalElement.offset().left + i,  
  11.                 top: $originalElement.offset().top + i,  
  12.                 margin: 0,  
  13.                 zIndex: zIndex,  
  14.                 opacity: opacity  
  15.             })  
  16.             .appendTo(‘body‘); //加入到body标签中  
  17.         }  
  18.     });  
  19. };  

 

   调用此对象方法:

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

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

11.5.2 参数映射

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

[javascript] view plaincopy
  1. //step3(参数映射)  
  2. jQuery.fn.shadow = function(opts) {  
  3.     return this.each(function() {  
  4.         var $originalElement = jQuery(this);  
  5.         for (var i = 0; i < opts.slices; i++) {  
  6.             $originalElement  
  7.         .clone()  
  8.         .css({  
  9.             position: ‘absolute‘,  
  10.             left: $originalElement.offset().left + i,  
  11.             top: $originalElement.offset().top + i,  
  12.             margin: 0,  
  13.             zIndex: opts.zIndex,  
  14.             opacity: opts.opacity  
  15.         })  
  16.         .appendTo(‘body‘);  
  17.         }  
  18.     });  
  19. };  

 

  

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

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

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

 

11.5.3  默认参数值

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

[javascript] view plaincopy
  1. //step4(默认参数值)  
  2. jQuery.fn.shadow = function(options) {  
  3.     var defaults = {  
  4.         slices: 10,  
  5.         opacity: 0.1,  
  6.         zIndex: -1  
  7.     };  
  8.     var opts = jQuery.extend(defaults, options);  
  9.   
  10.     return this.each(function() {  
  11.         var $originalElement = jQuery(this);  
  12.         for (var i = 0; i < opts.slices; i++) {  
  13.             $originalElement  
  14.          .clone()  
  15.          .css({  
  16.              position: ‘absolute‘,  
  17.              left: $originalElement.offset().left + i,  
  18.              top: $originalElement.offset().top + i,  
  19.              margin: 0,  
  20.              zIndex: opts.zIndex,  
  21.              opacity: opts.opacity  
  22.          })  
  23.          .appendTo(‘body‘);  
  24.         }  
  25.     });  
  26. };  

 

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

 

   调用方法如下:

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

 

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

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

});

 

11.5.4  回调函数

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

[javascript] view plaincopy
  1. //step5(回调函数)  
  2. jQuery.fn.shadow = function(options) {  
  3.     var defaluts = {  
  4.         slices: 5,  
  5.         opacity: 0.1,  
  6.         zIndex: -1,  
  7.         sliceOffset: function(i) {  
  8.             return { x: i, y: i };  
  9.         }  
  10.     };  
  11.   
  12.     var opts = jQuery.extend(defaluts, options);  
  13.     return this.each(function() {  
  14.         var $originalElement = jQuery(this);  
  15.         for (var i = 0; i < opts.slices; i++) {  
  16.             var offset = opts.sliceOffset(i);  
  17.             $originalElement  
  18.             .clone()  
  19.             .css({  
  20.                 position: ‘absolute‘,  
  21.                 left: $originalElement.offset().left + offset.x,  
  22.                 top: $originalElement.offset().top + offset.y,  
  23.                 margin: 0,  
  24.                 zIndex: opts.zIndex,  
  25.                 opacity: opts.opacity  
  26.             })  
  27.             .appendTo(‘body‘);  
  28.         }  
  29.     });  
  30. };  

 

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

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

 

11.5.5 可定制的默认值

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

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

[javascript] view plaincopy
  1. //step6 (可定制的默认值)  
  2. jQuery.fn.shadow = function(options) {  
  3.     var opts = jQuery.extend({},  
  4.      jQuery.fn.shadow.defaults, options); //defaults不被修改,使空映射{}成为被修改的新对象  
  5.   
  6.     return this.each(function() {  
  7.         var $originalElement = jQuery(this);  
  8.         for (var i = 0; i < opts.slices; i++) {  
  9.             var offset = opts.sliceOffset(i);  
  10.             $originalElement  
  11.         .clone()  
  12.         .css({  
  13.             position: ‘absolute‘,  
  14.             left: $originalElement.offset().left + offset.x,  
  15.             top: $originalElement.offset().top + offset.y,  
  16.             margin: 0,  
  17.             zIndex: opts.zIndex,  
  18.             opacity: opts.opacity  
  19.         })  
  20.         .appendTo(‘body‘);  
  21.         }  
  22.     });  
  23. };  
  24. jQuery.fn.shadow.defaults = {  
  25.     slices: 5,  
  26.     opacity: 0.1,  
  27.     zIndex: -1,  
  28.     sliceOffset: function(i) {  
  29.         return { x: i, y: i };  
  30.     }  
  31. };  

 

 

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

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

[javascript] view plaincopy
  1. $(document).ready(function() {  
  2.     $.fn.shadow.defaults.slices = 10;  
  3.   
  4.     $(‘h1‘).shadow({  
  5.         sliceOffset: function(i) {  
  6.             return { x: -i, y: i };  
  7.         }  
  8.     });  
  9. });  

 

 

11.6  自定义选择符表达式

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

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

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

[javascript] view plaincopy
  1. ///定义样式选择符表达式css  
  2. jQuery.extend(jQuery.expr[‘:‘], {  
  3.     ‘css‘: function(element, index, matches, set) {  
  4.         var parts = /([/w-]+)/s*([<>=]+)/s*(/d+)/  
  5.            .exec(matches[3]); /*matches:包含解析当前选择符的正则表达式结果的数组。matches[3],通常是这个数组中有用的项。对 
  6.                                :a(b)形式的选择符而言,matches[3]项包含着b,即圆括号中的文本*/  
  7.   
  8.         //选择元素属性值  
  9.         var value = parseFloat(jQuery(element).css(parts[1]));  
  10.         var selectedValue = parseInt(parts[3]);  
  11.         switch (parts[2]) { //匹配比较符,返回bool值,为真时,选择该元素;否则放弃该元素  
  12.             case ‘<‘:  
  13.                 return value < parseInt(parts[3]);  
  14.             case ‘<=‘:  
  15.                 return value <= parseInt(parts[3]);  
  16.             case ‘=‘:  
  17.                 return value == parseInt(parts[3]);  
  18.             case ‘>‘:  
  19.                 return value > parseInt(parts[3]);  
  20.             case ‘>=‘:  
  21.                 return value >= parseInt(parts[3]);  
  22.         }  
  23.     }  
  24. });  

 

 需要解释的如下:

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

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

[xhtml] view plaincopy
  1. <div>  
  2.         Deserunt mollit anim id est laborum</div>  
  3.     <div>  
  4.         Ullamco</div>  
  5.     <div>  
  6.         Ut enim ad minim veniam laboris</div>  
  7.     <div>  
  8.         Quis nostrud exercitation consequat nisi</div>  
  9.     <div style="width:60px">  
  10.         Ut aliquip</div>  
  11.     <div>  
  12.         Commodo</div>  
  13.     <div>  
  14.         Lorem ipsum dolor sit amet ex ea</div>  

 

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

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

 

 

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