全部文章搬运自个人我的主页:sheilasun.mecss
由于历来没写过jQuery插件,因此本文要经过一个轮播的例子,练习jQuery插件的写法。jquery
在讨论细节以前,先新建插件文件(固然也能够把代码直接放在页面的script标签中,只是复用麻烦些),如:'jQuery.carousel.js'。在文件中首先加入如下代码:ajax
(function($){ //...具体的实现 })(jQuery);
为何必定要用闭包包裹一层?缘由有二:c#
至关于c#中的静态方法,能够理解为给jQuery类添加静态方法。jQuery的全局函数也就是jQuery命名空间下的函数(如$.ajax(),$.each()等),这种添加方式也就是给jQuery命名空间下添加新函数。这种函数的特征是它不直接操做dom元素,能够说是工具类函数,所以不挂载在jQuery对象上。
这种方式下的函数写法也有多种:api
第一种数组
$.myAlert=function(){ window.alert("message from XX"); }
调用闭包
$.myAlert();
第二种 (能够一次添加多个函数)dom
$.extend({ myAlert:function(){ window.alert("message from XX"); }, myLog:function(){ window.console.log("message from XX"); } } );
调用jquery插件
$.myAlert();$.myLog();
第三种
在jQuery下再添加一层命名空间,将插件函数挂载在自定义的命名空间下,能够避免和jQuery以及其余插件的变量名或函数名冲突。ide
$.myPlugin.myAlert=function(){ window.alert("message from XX"); }
调用
$.myPlugin.myAlert();
给jQuery对象添加方法,也就是说,只有通过实例化的jQuery对象才能够调用咱们添加的方法。
这种方式下的函数写法也有多种:
第一种
$.fn.myAlert=function(){ window.alert("message from XX"); }
调用
$('.myButton').myAlert();
第二种 (能够一次添加多个函数)
$.fn.extend({ myAlert:function(){ window.alert("message from XX"); } } );
调用
//正确的调用 $('.myButton').myAlert(); $(this).myAlert(); $('#test li').myAlert(); //错误的调用 $.myAlert();//error
查看jQuery的源码就能知道,$.fn也就是jQuery.prototype,若是对原型有所了解就会知道,咱们对它进行扩展,天然全部的jQuery类的实例均可以访问到方法了。
不少的jQuery插件都是用这种方式,这样用jQuery选择器获取到jQuery对象之后,就能够调用插件方法。
本文的轮播插件也将依照这种类型来写。
使用过jQuery的人都知道它有一些很是棒的特性,如选择器后的隐式迭代、链式调用。
什么是隐式迭代?看下面这行代码,它会将整个页面上全部的p元素设成背景红色。
$('p').css('background','red');//隐式迭代
咱们本身写的插件也要尽可能支持这种隐式迭代,实现的方式也很简单,用each方法来遍历便可,代码以下:
$.fn.myLog=function(){ this.each(function(){//显式迭代 window.console.log(this); }); }
要注意的是,插件函数体内的'this'(上段代码中的第一个'this')即指的是当前经过选择器获取到的jQuery对象数组,而不像一般事件函数内部的'this'指的是dom元素。而代码中的第二个'this'则确实指的是一个dom元素了。
连缀语法
连缀指的是每次调用完把当前对象返回,供下次调用,这样能够一个方法接一个方法的连缀调用,中间用'.'隔开便可,除了连缀之外,我喜欢叫它链式调用更方便本身理解。下面这行代码就是连缀语法的一个例子。
$('p').css('background','red').slideDown();
能够看出,为了支持这种链式调用,插件除了执行本身的逻辑之外,最后还应该把当前的jQuery对象数组返回。因此上面的代码咱们能够修改以下:
$.fn.myLog=function(){ return this.each(function(){//return 当前对象 window.console.log(this); }); }
设置默认参数
插件内部能够设置默认参数,让用户在不传入参数的状况下也能够调用。当用户传入本身的参数时,对于用户有设置值的属性,用户设置的值覆盖默认值,对于用户没有设置值的属性,插件内部就用属性的默认值。这个覆盖操做能够用$.extend()方法实现,$.extend()用法能够戳官方API文档→http://api.jquery.com/jQuery.extend/。
(function($) { var defaults = { name: 'test', message: 'test message' }; $.fn.myLog = function() { return this.each(function(options) { //也能够用下面注释这句,只是这样defaults也会被改变 //var options=$.extend(defaults,options); var options = $.extend({}, defaults, options); window.console.log(options.name + ":" + options.message); }); } })(jQuery);
调用:
$('.className').myLog();//使用默认值 $('.className').myLog({name:'sheilasun'});//传入参数,覆盖默认值
还能够进一步改进,如今defaults在外界是没法获取的,咱们能够把它暴露出来,让用户能够在使用插件以前修改默认值。
(function($) { $.fn.myLog.defaults = { name: 'test', message: 'test message' }; $.fn.myLog = function() { return this.each(function(options) { var options = $.extend({}, $.fn.myLog.defaults, options); window.console.log(options.name + ":" + options.message); }); } })(jQuery);
调用:
$.fn.myLog.defaults={name:"sheilasun.me",message:'message from sheilasun.me'}; //或者 $.fn.myLog.defaults.name="sheilasun.me";
关于轮播的逻辑实现,放在下一篇写。