前言:javascript
今天作東西,考慮用戶最好的體驗,要實現界面上異步請求數據的loading效果,功能代碼都是別人寫完的,大概幾十個地方,用的都是jQuery的load方法。咋整啊,總不能挨個去每一個方法裏面加效果吧,幾十個地方呢。思來想去,只能用重寫了,嘛也不說了,開幹。java
做爲一名資深小白,以前從未重寫過jQuery的方法,依託着度娘,外加又看了看jquery的源碼,終於把問題解決了。因此以此博文,來小總結下學到的知識亦或幫助「同病相憐」的人,部分資源摘自網絡,若有紕漏,還望海涵並指出。jquery
往下翻頁以前,有必要了解如下知識:ajax
第一個括號裏邊的function($){….}實際上就是一個匿名函數,它的形參是$,這很奇怪,其實這裏主要是爲了避免與其它的庫衝突。咱們在調用函數的時候,一般都是函數名後邊加上括號以及實參,可是因爲操做符的優先級咱們定義的匿名函數也須要用()括起來,因此就有了前面的(function($){....})。網絡
如今這句代碼什麼意思你們應該很清楚了:第一個括號表示定義了一個匿名函數,而後(jQuery)表示爲該函數傳遞的參數,整個結合起來意思就是,定義了一個匿名函數,而後又調用該函數,並傳遞實參jQuery,至關於——function fun($){…};fun(jQuery);閉包
這種方法多用於存放開發的插件,執行其中的代碼時,Dom對象並不必定加載完畢。於此相反的是$(function(){}),這種方法在使用時頁面的Dom對象已經加載完畢了。事實上該方法的全寫是:$(document).ready(function(){});app
jQuery爲開發插件提拱了兩個方法,分別是:異步
jQuery.fn.extend(object);//爲jQuery的實例對象添加方法函數
jQuery.extend(object);//爲jQuery類自己擴展,添加新的方法或覆蓋原有的方法this
在jQuery中有以下源碼:
jQuery.fn = jQuery.prototype = { init: function( selector, context ) {//.... //...... };
由此看來jQuery.fn=jQuery.prototype,然而prototype是什麼呢?
在 JavaScript 中,每一個函數對象都有一個默認的屬性 prototype,稱爲函數對象的原型成員,這個屬性指向一個對象,稱爲函數的原型對象,當咱們每定義了一個函數的時候,JavaScript 就建立了一個對應的原型對象,也就是說,當咱們定義一個函數的時候,實際上獲得了兩個對象,一個函數對象,一個原型對象。原型對象是一個特殊的對象,函數的 prototype 成員指向它的原型對象,能夠經過函數對象的 prototype 成員取得這個原型對象的引用。
因此fn表示的就是原型對象,而extend表示擴展,因此$.fn.extend表示的是爲原型對象擴展方法,使用此方式擴展的方法只能用對象去調用,example:
$.fn.extend({ test:function(){ alert("test"); } }); $("#id").test();
此方式則表示爲jQuery類添加類方法(雖然jQuery沒有類的概念,但用類來理解彷佛簡單了很多),或者直接理解爲添加靜態方法,而後就能夠直接用$在其餘地方來調用此擴展方法了,example:
$.extend({ test:function(param){ alert(param); } }); $.test(1);//則直接彈出1
閉包是js的難點也是js的特點,不少高級應用都要依靠閉包來實現,網絡資源不少,在這裏不在贅述,最好也去了解下。
這兩個概念也是有必要知道的,詳見我轉載的文章:點擊這裏
(function($){ //首先備份下jquery的ajax方法 var_ajax=$.ajax; //重寫jquery的ajax方法 $.ajax=function(opt){ //備份opt中error和success方法 var fn = { error:function(XMLHttpRequest, textStatus, errorThrown){}, success:function(data, textStatus){} } if(opt.error){ fn.error=opt.error; } if(opt.success){ fn.success=opt.success; } //擴展加強處理 var_opt = $.extend(opt,{ error:function(XMLHttpRequest, textStatus, errorThrown){ //錯誤方法加強處理 fn.error(XMLHttpRequest, textStatus, errorThrown); }, success:function(data, textStatus){ //成功回調方法加強處理 fn.success(data, textStatus); }, beforeSend:function(XHR){ //提交前回調方法 $('body').append("<div id='ajaxInfo' style=''>正在加載,請稍後...</div>"); }, complete:function(XHR, TS){ //請求完成後回調函數 (請求成功或失敗以後均調用)。 $("#ajaxInfo").remove();; } }); return _ajax(_opt); }; })(jQuery);
//一樣先備份下jquery的load方法 var _load=$.fn.load; $.fn.extend({ load:function(url,param,calbck){ //其餘操做和處理 //.. //此處用apply方法調用原來的load方法,由於load方法屬於對象,因此不可直接對象._load(...) return _load.apply(this,[url,param,calbck]); } });