全部文章搬運自個人我的主頁: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";
關於輪播的邏輯實現,放在下一篇寫。