在早期的开发中,正如前面闭包中所提到的那样,人们一开始并没有意识到要开发出插件这么个玩意儿,都是遇到啥写啥。在长期的工作中,人们发现很多代码是重复的,写了一遍又一遍,以登录页面为例,每写一次都需要重新校验username、password、email、tel等等内容,这些工作毫无意义只是简单地重复,而且大多数都是大同小异,人们开始不耐烦了,并且着手去找到一种办法,希望能够从这些简单无意义的重复劳动中解放出来。既然写这些代码不可避免,那么能否减少写这些代码的次数呢?更进一步的思考,能不能有这么一种方式,当我需要这段代码的时候,我就可以直接拿来用,哪怕只是做一点点更改也行。这样插件就应运而生了。它封装了某个功能,实现了代码的可重用性,在实际工作中可以拿来反复的使用。

  一个最最简单的jquery插件只有一个函数来实现一个功能就够了,它仅仅只需要用来被重复调用。比如我的工作中要实现这么一个功能:当我点击时,改变div框中的背景颜色。这个功能在页面中需要反复被使用到,那么我就迫切地需要开发一个插件来实现它。下面是不使用任何插件的情况下,每一次页面的使用都需要重新写。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="jquery-1.11.3.js"></script>
<style>
div{
width:200px;
height:200px;
border:1px solid #000;
}
</style>
</head>
<script>
$(function(){
$("input").click(function(){
$("div").css("background","#ccc");
})
});
</script>
<body>
<input type="button" value="动我一下试试"><br><br>
<div></div>
</body>
</html>

这里将给出全部代码,下文中为避免啰嗦将只给出关键代码。当开发插件时它的插件的代码如下:

 jQuery.fn.extend({
test : function(){
$(this).css("background","#ccc");
}
})//插件名为下文的plugins.js

它的调用代码

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script src="jquery-1.11.3.js"></script>//引入jquery
<script src="plugins.js"></script>//引入jquery插件
<style>
div{
width:200px;
height:200px;
border:1px solid #000;
}
</style>
</head>
<script>
$(function(){
$("input").click(function(){
$("div").test(); //调用插件中的test()方法
})
});
</script>
<body>
<input type="button" value="动我一下试试"><br><br>
<div></div>
</body>
</html>

  在上面的插件代码中,我们发现test()方法是嵌套在jQuery.fn.extend()中,那么这个jQuery.fn.extend()到底是什么呢?事实上,绝多大数插件都是基于它开发的,它就是大名鼎鼎的jquery对象方法插件机制,与之齐名的还有jQuery.extend(),也就是jquery全局函数插件机制。他们都被用来创建插件,在继续下文之前,很有必要来了解下二者的区别。

  一、jQuery.extend()

  事实上,当jQuery.extend()用来做插件开发的时候,在其参考文档中表述的是用来在jQuery命名空间上增加新函数。此处的jQuery可以理解为一个function类,对它进行extend扩展实际上就相当于给他添加一个静态方法,这个方法是扩展在jQuery类上面的,它的调用是不需要new出一个实例,而是直接采用“jQuery+方法”的形式调用,与jQuery的实例没有任何关系。借用参考文档的例子:

jQuery代码:

 jQuery.extend({
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
});

运行结果:

 jQuery.min(2,3); // => 2
jQuery.max(4,5); // => 5

  二、jQuery.fn.extend()

  在jQuery.fn.extend()中,从底层代码知道fn代表的是prototype,它实际上是扩展jQuery对象也就是原型prototype上的方法,既然是扩展在jQuery对象上的方法,那么就是说要jQuery对象才能调用喽。而什么是jQuery对象呢?不就是jQuery的实例吗?换个方式来说,$(selector)不就是jQuery对象吗?这正如前面的例子所述,调用的时候是$("div").test(),而$("div")是jQuery对象。

  jQuery代码:

1 jQuery.fn.extend({
2 test : function(){
3 $(this).css("background","#ccc");
4 }
5 })

  调用代码:

 $(function(){
$("input").click(function(){
$("div").test(); //调用插件中的test()方法 ,用的是$("div")而非$
})
});

  通过区别比较上面2种开发插件的方式,可以看到基于对象方法机制插件使用会广泛得多,现实中大部分都是基于对象方法开发的插件。

  然而在上述例子中,那个简单的插件很快就遇到了新的问题。随着页面的复杂性增加,在代码中会引入多个库或框架,$这么火热,大家都想套套近乎沾沾光,于是大家的命名都采取了$,一个不小心,$的指代就会被第三方库或框架给覆盖了,它指代的就不再是jquery而是第三方库了。这就是jquery多库共存问题。

  对于jquery多库共存问题,参考文档给出了解决方案,有时候,你不得不为一些精妙绝伦的解决方案而拍案叫绝。

  一、jQuery.noConflict()

  运行这个函数将变量$的控制权让渡给第一个实现它的那个库。这有助于确保jQuery不会与其他库的$对象发生冲突。在运行这个函数后,就只能使用jQuery变量访问jQuery对象。例如,在要用到$("div p")的地方,就必须换成jQuery("div p")。代码如下: 

1 jQuery.noConflict();
2 // 使用 jQuery
3 jQuery("div p").hide();//此处不再使用$而是使用jQuery
4 // 使用其他库的 $()
5 $("content").style.display = 'none';

 二、创建一个新的别名用以在接下来的库中使用jQuery对象:

1 var j = jQuery.noConflict();
2 // 基于 jQuery 的代码
3 j("div p").hide();
4 // 基于其他库的 $() 代码
5 $("content").style.display = 'none';

  三、创建一个匿名函数(function($){})(jQuery):

1 jQuery.noConflict();
2 (function($) {
3 $(function() {
4 // 使用 $ 作为 jQuery 别名的代码
5 });
6 })(jQuery);
7 // 其他用 $ 作为别名的库的代码

  这是一个匿名函数,这个函数可以理解为这样:

1 var f= function ($){
2 $(function(){
3
4 });
5 }
6 f(jQuery);

  对于函数f,$作为形参,是局部变量,可以在函数内部自由滴使用$,当他被调用时,jQuery作为实参被传递进去。这样做的好处就是,函数f里定义的函数和变量仅仅在函数f里有效,$并不会与外面的$相冲突。调用执行时,jQuery会取代形参$,这样既实现了让$指代了jQuery,又避免了$之间的互相冲突,这也是使用的最多的方案。

  上面的插件就该是:

1 (function($){
2 $.fn.extend({
3 test : function(){
4 $(this).css("background","#ccc");
5 }
6 })
7 })(jQuery)

  这样就创建了一个方便使用的对象方法插件,同时解决了多库共存的问题。

  然而现实问题并没有这么简单,虽然完成了插件的基本功能,但是还不够,用户在长期的使用过程中,觉得不够智能,他想自定义div框的颜色,而不仅仅是灰色;同时他还想能够改变框的大小。好吧,问题又来了,但是没关系,程序员天生就是来解决问题的。

  怎么办?首先想到的就是传递参数进来,给test()增加参数,这个参数可以让用户自定义,用户想怎样就怎样,这个好解决。我们来看下面代码:

1  (function($){
2 $.fn.extend({
3 test : function(opts){
4 $(this).css(opts);
5 }
6 })
7 })(jQuery)

在调用时代码如下:

$("div").test({width:"500px",background:"red"})

  这样来看问题得到解决,但,这还不够完美。假如说test有许多参数怎么办?用户只想定义其中一部分参数,其他的保持不变怎么办?用户怎么知道允许自定义哪些参数?最好的解决方式无疑是:指明哪些参数用户可以去自定义,当用户需要定义某些参数时,尽管自定义好了,其他的参数不变,使用插件的默认值。

  这里就有如下的解决办法:

var opts=$.extend(defaluts,opts)

  $.extend() 除了可以用来创建插件之外,还可以进行对象合并,这里只讲此处需要用到的用法,更多用法参照http://api.jquery.com/jQuery.extend/,或者可以看我稍后的中文翻译http://www.cnblogs.com/liudaxia/p/4910106.html。举例来说明: 

 1   var Amy={
2 age:20,
3 sex:gril,
4 }
5 var Dale={
6 age:20,
7 sex:boy
8 weight:120
9 }
10 $.extend(Amy,Dale)//此时的Amy={age:20,sex:boy,weight:120}

  可以看到,Amy的属性被修改,它继承了Dale的weight属性,同时sex属性被覆盖。这对于我们要实现的功能有什么用呢?假如说,我们把默认值放在Amy的位置,把传进来的参数opts放在Dale的位置,会有什么样的效果呢?显而易见,新传进来的自定义参数属性将会被保留,而默认值的相同的属性则会用户自定义的给覆盖,这样就巧妙的实现了我们想要的效果。用上面的实例来说明,看插件代码:

jQuery.fn.extend({
test : function(opts){
var defaults={// 默认值设置,此处与html代码中的div的style设置保持一致。
width:"200px",
 background:"#fff",
height:"200px"
}
var s=$.extend(defaults,opts);// s为合并之后的属性,它是{width:"500px",background:"red",height:"200px"}
$(this).css(s);
}
})

调用代码:

$("div").test({width:"500px",background:"red"})

  最终得到的效果就是宽500高200的红色矩形。原来默认的高200属性得到保留,用户想要的改变宽和颜色的目的也达到。用户在调用的时候,想自定义哪个参数,就把哪个参数传进去,同时没被定义的属性将会被保留。

  还可以对其进行优化,比如假如获取的div框不止一个,那么这个时候就需要使用each()进行遍历。甚至可以把用户不自定义参数的情况考虑进去,这些都比较简单,就不具体介绍了。那么最终的插件如下:

 1 (function($){
2 $.fn.extend({//下面的opts就是用户自定义的参数
3 test : function(opts){//定义test()方法,这就是我们的插件。可以改写成$.fn.test=function(opts){}
4 var defaults={// 默认值设置,此处与html代码中的div的style设置保持一致。
5 width:"200px",
6   background:"#fff",
7 height:"200px"
8 }
9 opts=opts||{};//opts可能为空,也就是用户没有自定义,此时使用默认值
10 var s=$.extend(defaults,opts);// s为合并之后的属性,它是{width:"500px",background:"red",height:"200px"}
11 this.each(function(){//遍历
12 $(this).css(s); //功能实现代码,也就是改变div框的宽和背景颜色
13 });
14 }
15 })
16 })(jQuery)

  以上就是一个简单的插件的开发过程。本人也是初学,欢迎指出错误共同探讨交流共同进步,谢谢。

JavaScript之三:jQuery插件开发(一)的更多相关文章

  1. javascript笔记——jQuery插件开发的几种方式

    jQuery插件开发分为两种: 1 类级别  类级别你可以理解为拓展jquery类,最明显的例子是$.ajax(...),相当于静态方法. 开发扩展其方法时使用$.extend方法,即jQuery.e ...

  2. javascript 和 jquery插件开发

    window.onload 页面加载完成后执行 window.onload = function () { function dom(id) { return document.getElementB ...

  3. JavaScript学习笔记(四)——jQuery插件开发与发布

    jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非常多,随着版本的不停迭代越来越稳定好用, ...

  4. JavaScript学习总结(四)——jQuery插件开发与发布

    jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非常多,随着版本的不停迭代越来越稳定好用, ...

  5. JavaScript学习总结(五)——jQuery插件开发与发布

    jQuery插件就是以jQuery库为基础衍生出来的库,jQuery插件的好处是封装功能,提高了代码的复用性,加快了开发速度,现在网络上开源的jQuery插件非常多,随着版本的不停迭代越来越稳定好用, ...

  6. jQuery插件开发精品教程,让你的jQuery提升一个台阶

    要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统.这好比大公司们争相做平台一样,得平台者得天下.苹果,微软,谷歌等巨头,都有各自的平台及生态圈 ...

  7. jquery插件开发

    jQuery是一个封装的很好的类,比如我们用语句$("#btn1") 会生成一个 jQuery类的实例. 一.jQuery插件开发注意要点 1.使用闭包,避免全局依赖,避免第三方破 ...

  8. 从零开始学jQuery插件开发

    http://www.w3cfuns.com/notes/19462/ec18ab496b4c992c437977575b12736c.html jQuery 最成功的地方,是它的可扩展性,通过吸引了 ...

  9. jquery插件开发继承了jQuery高级编程思路

    要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统.这好比大公司们争相做平台一样,得平台者得天下.苹果,微软,谷歌等巨头,都有各自的平台及生态圈 ...

  10. jQuery插件开发(转)

    jQuery插件开发全解析 jQuery插件的开发包括两种: 一种是类级别的插件开发,即给jQuery添加新的全局函数,相当于给jQuery类本身添加方法.jQuery的全局函数就是属于jQuery命 ...

随机推荐

  1. JAVA中各种去除空格

    1. String.trim() trim()是去掉首尾空格 2.str.replace(" ", ""); 去掉所有空格,包括首尾.中间 String str ...

  2. openGL点精灵PointSprite具体解释: 纹理映射,旋转,缩放,移动

    第一,什么是点精灵 openGL的图形由顶点构成,以后利用顶点进行纹理的映射.点精灵就是,一个顶点被当作一个精灵来处理.特别之处就是,一个顶点也可进行纹理贴出.比如,原来是个顶点构成的一个矩形,如今一 ...

  3. Linux命令对应的全称解释(转)

    Filesystem Hierarchy Standard(FHS) /:根目录,所有的目录.文件.设备都在/之下,/就是Linux文件系统的组织者,也是最上级的领导者.  /bin:bin 就是二进 ...

  4. Java容器的概要

    [Java流输入/输出原理] 在Jaav程序.对于输入数据/输出操作"流"(stream)时尚:J2SDK它提供了多种 各种各样的"流"类,用于获得不同类型的数 ...

  5. 二十7天 春雨滋润着无形 —Spring依赖注入

    6月11日,明确."夏条绿已密,朱萼缀明鲜.炎炎日正午,灼灼火俱燃." IT人习惯把详细的事物加工成的形状一致的类.正是这种一致,加上合适的规范.才干彰显对象筋道的牙感和bean清 ...

  6. HDU 1394 Minimum Inversion Number (数据结构-段树)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  7. WPF 图片浏览 伪3D效果

    原文:WPF 图片浏览 伪3D效果 首先上效果图: 因项目要求,需要把图片以"好看"."炫"的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果 ...

  8. 修改系统环境变量 cmd命令

    详细大家对cmd的使用都有了一些简单的了解,但是困扰大家的主要的问题就是: cmd命令修改环境变量有两种方式:1. 短期内有效,在关闭dos窗口后就自动失效 2.长期有效,关闭dos窗口后还有效 下面 ...

  9. c# 获取某个对象的[公有属性]的名称,类型,值

    /// <summary> /// 获取某个对象的[公有属性]的名称,类型,值 /// </summary> /// <typeparam name="T&qu ...

  10. uva 1401 dp+Trie

    http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&page=show_problem& ...