一、如何开发一个jquery插件

       jquery插件的开发包括两种:

                  1、类级别的插件开发(jQuery.extend(Object)):既给jQuery类添加类方法,可以理解为类的 “静态方法”

                         如:

jQuery.extend({
   add:function(a,b){
         alert(a+b);
   }
});

那么我们调用就可以使用:$.add(1,2);

                  当然对其进行添加jQuery的全局函数还有其他的方法如:jQuery.foo = function(){  alert('foot'); }; 调用的时候可以使用 : $.foo();

             这种直接在jQuery命名空间中定义函数,有时候还是会产生名字相同的问题,这时候最好的办法是将我们的插件定义在我们自己定义的命名空间下面

$.myPlus = {
		   add:function(a,b){
		       alert(a+b);
		   },
		   foo:function(){
		       alert('foo2');
		   }
		};
		$.myPlus.add(3,4);
		$.myPlus.foo();



                2、对象级别的插件开发(jQuery.fn.extend(Object)): 既给jQuery对象添加方法。

                  那么jQuery.fn是什么呢?

                  由源码可以看出:

                   

jQuery.fn = jQuery.property = {
           init:function(selector,context){}
      }

                这样就知道是对jQuery.property进行扩展(为jQuery类,添加成员方法,然后由具体的实例对象进行调用),如:

$.fn.extend({
	       myClick:function(){
		     $(this).click(function(){
			    alert('my click !');   
			 });  
		   }
	   });
	   $('a').myClick();



               当然我们也可以使用 $.fn.myClick = function(){   ...   }; 来达到同样的效果。


              但是如果我们需要分解我们插件的实现代码为多个函数时,该怎么办?(也就是在同一个命名空间下面定义多个函数),这个时候我们可以使用

             命名空间来进行申明,如:

 

$.fn.myDiv = function(options){
	        //定义默认的参数值
			var defaults = {
			    height:'100px',
				width:'100px',
				background:'red'
			};
			//使用新值替换默认值
			var opts = $.extend(defaults,options);
			$(this).width(opts.height).height(opts.width).css('background',opts.background);
	   };
	   $('div').myDiv();



               接下来我们需要对上面的myDiv() 进行改进  !!!!!!

        改进一:暴露插件的默认设置

               这样的改进让插件的使用者更容易用较少的代码覆盖和修改插件。

$.fn.myDiv = function(options){
			//使用新值替换默认值
			var opts = $.extend({},$.fn.myDiv.defaults,options);
			$(this).width(opts.height).height(opts.width).css('background',opts.background);
	   };
	    //定义默认的参数值
		$.fn.myDiv.defaults = {
			    height:'100px',
				width:'100px',
				background:'red'
		};
        //通过这样一行代码,就可以覆盖掉插件中的默认设置的背景色为蓝色,只需调用一次
		//且不一定要放在ready中进行调用
        $.fn.myDiv.defaults.background = 'blue';

       //这里使用新的背景色缺省值来调用插件
	   $('div').myDiv();
	   //这里通过传递配置参数给插件方法来覆盖缺省默认值
	   $('div').myDiv({background:'green'});




       改进二:适当的暴露一些函数

                  这样可以让其他人扩展你的插件(为你的插件写插件)

$.fn.myDiv = function(options){
			//使用新值替换默认值
			var opts = $.extend({},$.fn.myDiv.defaults,options);
			$(this).width(opts.height).height(opts.width).css('background',opts.background);
            $.fn.myDiv.textSize($(this));
			return $(this);
	   };
	    //定义默认的参数值
		$.fn.myDiv.defaults = {
			    height:'100px',
				width:'100px',
				background:'red'
		};
		//定义默认的实现方法(并暴露出来)
		$.fn.myDiv.textSize = function(objs){
		    objs.css('font-size','40px');
		};

        $('div').myDiv().css('color','yellow');



   如果别人想来对你的textSize进行扩展可以编写如下代码(只需要调用一次)

$.fn.myDiv.textSize = function(objs){
		    objs.css('font-size','80px');
		};




        改进三:保持私有函数的私有性(闭包)

                    那么我们怎么定义更多的函数而不搅乱命名空间也不暴露实现呢?使用闭包功能

$.fn.myDiv = function(options){
			//使用新值替换默认值
			var opts = $.extend({},$.fn.myDiv.defaults,options);
			$(this).width(opts.height).height(opts.width).css('background',opts.background);
            $.fn.myDiv.textSize($(this));

			debug($(this));
			return $(this);
	   };
	    //定义默认的参数值
		$.fn.myDiv.defaults = {
			    height:'100px',
				width:'100px',
				background:'red'
		};
		//定义默认的实现方法(并暴露出来)
		$.fn.myDiv.textSize = function(objs){
		    objs.css('font-size','40px');
		};
		//添加一个私用的函数
		function debug($obj){
		  if(window.console && window.console.log){
		      window.console.log(' height: '+$obj.css('height'));
		  }
		}
       //外部调用
       $('div').myDiv().css('color','yellow');




二、完整例子(简单案例)

插件名称:jquery.myDiv.js

(function($){
	     $.fn.myDiv = function(options){
			//使用新值替换默认值
			var opts = $.extend({},$.fn.myDiv.defaults,options);
			$(this).width(opts.height).height(opts.width).css('background',opts.background);
            $.fn.myDiv.textSize($(this));

			debug($(this));
			return $(this);
	   };
	    //定义默认的参数值
		$.fn.myDiv.defaults = {
			    height:'100px',
				width:'100px',
				background:'red'
		};
		//定义默认的实现方法(并暴露出来)
		$.fn.myDiv.textSize = function(objs){
		    objs.css('font-size','40px');
		};
		//添加一个私用的函数
		function debug($obj){
		  if(window.console && window.console.log){
		      window.console.log(' height: '+$obj.css('height'));
		  }
		}
	 })(jQuery);



  具体调用:

<!doctype html public "-//w3c//dtd html 4.0 tRANSITIONAL//en">
<html>
 <head>
  <title> nEW dOCUMENT </title>
  <meta name="gENERATOR" content="eDITpLUS">
  <meta name="aUTHOR" content="">
  <meta name="kEYWORDS" content="">
  <meta name="dESCRIPTION" content="">
  <script type = "text/javascript" src = "jquery-1.8.3.js"></script>
  <script type = "text/javascript" src = "jquery.myDiv.js"></script>
  <script type = "text/javascript">
      $(function(){
         $('div').myDiv().css('color','yellow');
	  });
  </script>
 </head>

 <body>
	<div>divdiv</div>
	<div>divdiv</div>
 </body>
</html>


三、 知识点扩充

     1、 jQuery.extend(Object) 函数详解

              A、 该方法的原型是:   $.extend(dest,src1,src2...);

       它的含义是将src1,src2,src3...合并到dest中,返回值为合并后的dest,由此可以看出该方法合并后,是修改了dest的结构的。如果想要得到合并的结果却又不想修改dest的结构,可以如下使用:

var newSrc=$.extend({},src1,src2,src3...)//也就是将"{}"作为dest参数。



具体案例:

    

var result=$.extend({},{name:"Tom",age:21},{name:"Jerry",sex:"Boy"});

//那么合并后的结果
result={name:"Jerry",age:21,sex:"Boy"};

也就是说后面的参数如果和前面的参数存在相同的名称,那么后面的会覆盖前面的参数值。



                B、省略dest参数: $.extend(src);

           如果省略了,则该方法就只能有一个src参数,而且是将该src合并到jquery的全局对象中去。(类变量)

          $.fn.extend(src);

          该方法将src合并到jquery的实例对象中去。(实例变量)


               C、$.extend(boolean,dest,src1,src2.....);

                              第一个参数boolean代表是否进行深度拷贝,其余参数和前面介绍的一致


具体案例:

var result=$.extend( true,  {},  
    { name: "John", location: {city: "Boston",county:"USA"} },  
    { last: "Resig", location: {state: "MA",county:"China"} } );

//结果
result={name:"John",last:"Resig",
        location:{city:"Boston",state:"MA",county:"China"}}

将src中的嵌套子对象也进行合并。


var result=$.extend( false, {},  
{ name: "John", location:{city: "Boston",county:"USA"} },  
{ last: "Resig", location: {state: "MA",county:"China"} }  
                    ); 

//结果
result={name:"John",last:"Resig",location:{state:"MA",county:"China"}}

直接覆盖其外层对象。