《锋利的jQuery》读书笔记 -- 编写jQuery插件

1. 插件的种类

       编写插件的目的是给已经有的一系列方法或函数做一个封装,以便在其他地方重复使用,方便后期维护和提高开发效率。

       jQuery的插件主要分为3种类型。

1.1 封装对象方法的插件

       这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是常见的一种插件。jQuery 的 parent() 方法、appendTo() 方法和 addClass() 方法都是输入这类插件。

1.2 封装全局函数的插件

       可以将独立的函数加到 jQuery 命名空间下。常用的 jQuery.ajax() 方法以及去除首尾空格的 jQuery.trim() 方法等,都是 jQuery 作为全局函数的插件附加到内核上去的。

1.3 选择器插件

       个别情况下,会需要用到选择器插件。虽然 jQuery 的选择器十分强大,但还是会需要扩充一些自己喜欢的选择器,例如用 :color(red) 来选择虽有红色字的元素之类的想法。

2. 插件的基本要点

  • jQuery 插件的文件名推荐命名为 jquery(插件名).js,以免和其他 JavaScript 库插件混淆。例如命名为 jquery.color.js
  • 所有对象方法都应该附加到 jQuery.fn 对象上,而所有的全局函数都应该附加到 jQuery 对象本身上。
  • 在插件内部,this指向的是当前通过选择器获取的 jQuery 对象,而不像一般的方法那样,例如 click() 方法,内部的 this 指向的是 DOM 元素。
  • 可以通过 this.each 来遍历所有元素。
  • 所有的方法或函数插件,都应当以分号,否则压缩的时候可能出现问题,为了更稳妥些,甚至可以在插件头部先加上一个分号,以免他人的不规范代码给插件带来影响
  • 插件应该返回一个 jQuery 对象,以保证插件的可链式操作,除非插件需要返回的是一些需要获取的量,例如字符串或者数组等。
  • 避免在插件内部使用$作为 jQuery  对象的别名,而应该使用完整的 jQuery 来表示。这样可以避免冲突,当然,也可以利用闭包技巧来回避这个问题,使插件内部继续使用 $ 作为 jQuery 的别名

3. 插件中的闭包

       关于闭包,ECMAScript 对其进行了简单的描述:允许使用内部函数(即函数定义和函数表达式位于另一个函数的函数体内),而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数,当其中的一个这样的内部函数在包含它们的外部函数之外呗调用时,就会形成闭包。利用闭包的特性,既可以避免内部临时变量影响全局空间,又可以在插件内部继续使用$作为 jQuery 的别名。常见的 jQuery 插件都是以下这种形式的:
;(function($) {
    /* 这里放置代码 */
})(jQuery);
       首先定义一个匿名函数 function(){/*这里放置代码*/},然后用括号括起来,变成 (function(){/*这里放置代码*/}) 这种形式,最后通过 () 这个运算符来执行。可以传递参数进去,以供内部函数使用。
// 注意为了更好的兼容性,开始前有个分号
;(function($) {        // 此处将 $ 作为匿名参数的形参
    /* 这里放置代码,可以使用$作为jQuery的缩写别名 */
})(jQuery);    // 这里就将 jQuery 作为实参传递给匿名函数了

4. jQuery 插件的机制

       jQuery 提供了两个用于扩展 jQuery 功能的方法,即 jQuery.fn.extend() 方法和 jQuery.extend() 方法。前者用于扩展之前提到的3种类型插件中的第1种,后者用于扩展后两种插件。这两个方法都接受一个参数,类型为 Object。Object 对象的 “名/值对” 分别代表 “函数或者方法名/函数主体”。具体内容将会在下面讲解。
       jQuery.extend() 方法除了可以用于扩展 jQuery 对象之外,还有一个很强大的功能,就是用于亏哦站已有的 Object 对象。
       jQuery 代码如下:
jQuery.extend(target, obj1,......,[objN])
       用一个或多个其他对象来扩展一个对象,然后返回被扩展的对象。 例如合并 settings 对象和 options 对象,修改并返回 settings 对象。
var settings = { validate: false, limit: 5, name: "foo"};
var options = { validate: true, name: "bar"};
var newOptions = jQuery.extend(settings,options);
       结果为:
newOptions = { validate: true, limit: 5, name: "bar"};
       jQuery.extend() 方法经常用于设置插件方法的一系列默认参数,如下面代码所示:
function foo(options) {
    options = jQuery.extend({
        name: "bar",
        length: 5,
        dataType: "xml"      /* 默认参数 */
    }, options);  /* options 为传递的参数 */
};
       如果用于调用 foo() 方法的时候,在传递的参数 options 对象中设置了相应的值,那么使用设置的值,否则使用默认值。代码如下:
foo({ name: "a", length: "4", dataType: "json"};
foo({ name: "a", length: "4"};
foo({ name: "a"};
foo(};
       通过使用 jQuery.extend() 方法,可以很方便地使用传入的参数来覆盖默认值。

5. 编写 jQuery 插件

5.1 封装 jQuery 对象方法的插件

       首先介绍如何编写一个 color() 插件。该插件用于实现以下两个功能。
       (1)设置匹配元素的颜色。
       (2)获取匹配的元素(元素集合中的第1个)的颜色。
       由于是对 jQuery 对象的方法扩展,因此采用扩展的第1类插件的方法 jQuery.fn.extend() 来编写,代码如下:
;(function($){
    $.fn.extend({
        "color": function(value){
            if(value == undefined) {
                return this.css("color");
            } else {
                // 返回jquery对象,使之支持链式操作
                return this.css("color", value);
            }                   
        }
    });
})(jQuery);
       编写完成后,就可以使用$(selector).corlor()获取颜色,使用$(selector).css("color", color); 设置颜色了

5.2 封装全局函数的插件

    这类插件是在 jQuery 命名空间内部添加一个函数。这类插件很简单。只是普通的函数。
    下面定义了去掉左侧空白符和右侧空白符全局函数
;(function($){
	$.extend({
		ltrim: function(text){
			return (text || "").replace(/^\s+/g, "");
		},
        rtrim: function(text) {
            return (text || "").replace(/\s+$/g, "");
        }
	});
})(jQuery);

5.3 自定义选择器

        jQuery 提供了一套方法让用户可以通过制作选择器插件来使用自定义选择器。从而使 jQuery 的选择器功能更加完善。
        jQuery 的选择器解析器首先会使用一组正则表达式来解析选择器,然后对解析出的每个选择符执行一个函数,称为选择器函数。最后根据这个选择器函数的返回值为 true 还是 false 来决定是否保留这个元素。这样就可以找到匹配的元素节点。
        下面是一个选择器例子:
$('div:gt(1)')
        该选择器首先会获取所有的 <div> 元素,然后隐式遍历这些 <div> 元素,并逐个将这些 <div> 元素作为参数,连同括号里的 “1” 等一些参数(具体见下文)一起传递给 gt 对应的选择器函数进行判断。如果这个函数返回 true,则这个 <div> 元素保留;如果返回 false,则不保留这个 <div> 元素。这样得到的结果就是一个符合要求的 <div> 元素的集合。
       :gt() 选择器在 jQuery 源文件中的代码如下:
gt: function(a, i, m) {
        return i>m[3]-0;
}
       其中,选择器的函数一共接受3个参数,代码如下:
function(a, i, m) {
        // ...
}
       第1个参数为 a,指向的是当前便利到的 DOM 元素。
       第2个参数为 i,指的是当前便利到的 DOM 元素的索引值,从0开始。
       第3个参数m最为特别,它是由 jQuery 正则解析引擎进一步解析后的产物(用 match 匹配出来),是一个数组。
  • m[0],以上面的 $('div:gt(1)') 这个例子来讲,是 :gt(1) 这部分。它是 jQuery 选择器进一步将要匹配的内容
  • m[1],这里是选择器的引导符,匹配例子中的 ":",即冒号,并非只能使用 ":' 后面跟上选择器,用户还可以自定义其他的选择器引导符
  • m[2],即例子中的 gt,确定究竟是调用哪个选择器函数。
  • m[3],即例子中括号里的数字 “1”,它非常有用,是编写选择器函数最重要的一个参数。 
  • m[4],上面的例子中没有体现出来,这个比较汉奸,例如 "div:l(ss(dd))" 这样一个选择器中,m[4]就指向了 (dd) 这部分,注意是带括号的 (dd),而不是dd。同时要注意,此时的m[3]的值是 ss(dd) 而非 ss。
       下面构造一个 between 选择器
;(function($){
    // between选择器,例如使用$('div:between(2,5)')能实现获取索引值为3、4元素的功能
    // 貌似1.10.1版本下不能正常工作
	$.extend(jQuery.expr[":"], {
        // 选择器函数一共接受3个参数,
        //第一个参数a指向当前遍历到的元素;第2个参数i,指的是当前遍历到的DOM元素的索引值,从0开始
        //第三个参数,是由jQuery正则解析引擎进一步解析后的产物,是一个数组
		between: function(a, i, m){
			var tmp = m[3].split(',') //以逗号为分隔符,切成一个数组
            return tmp[0]-0<i && i<tmp[1]-0; //tmp[0]为字符串类型,通过tmp[0]-0将其转换为数字
		}
	});
})(jQuery);
       这里再次利用 jQuery.extend() 方法来对 jQuery 对象的一部分进行扩展。选择器仅仅是 jQuery.expr[":"] 对象的一部分,同时也是一个 Object 对象,因此可以直接利用 jQuery.extend() 对其进行扩展。
       选择器插件中的函数属于运算密集型函数,对执行效率要求很高,在编写此类插件的时候一定要秉承优化再优化的原则。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值