上一篇文章 ,講解了jQuery.ajax函數。這篇文章將其他一些細節補充完。下一篇文章則開始講解,jQuery是如何將script動態載入、XMLHttpRequest、JSONP一起包裝進jQuery.ajax里的。
?
jQuery.ajaxSetup
我們可以從主函數看出,參數是通過jQuery.ajaxSetup產生的:
// 通過jQuery.ajaxSetup改造參數對象 s = jQuery.ajaxSetup( {}, options ),
那么jQuery.ajaxSetup在干些什么呢?
jQuery.ajaxSetup = function ( target, settings ) { // 如果有參數 return settings ? // 創建一個設置對象,先將jQuery.ajaxSettings的屬性放進去, // 然后將參數也放進去 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // 并將設置對象的屬性放進jQuery.ajaxSettings對象里 ajaxExtend( jQuery.ajaxSettings, target ); };
?
ajaxExtend
ajaxExtend和jQuery.extend有一些不同,避免有些不需要深復制的屬性進行深復制。
function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; // 遍歷src對象中的所有key for ( key in src ) { // 如果值不是undefined if ( src[ key ] !== undefined ) { // 判斷是不是不需要深復制的,如果不需要深復制,將屬性直接寫進target, // 否則寫進deep里存起來 // 我們可以從jQuery.ajaxSettings.flatOptions看到, // 實際上不需要深復制的是url和context ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; } } // 如果deep不是undefined,證明需要深復制 if ( deep ) { // 開始深復制 jQuery.extend( true , target, deep ); } // 返回target return target; }
?
ajaxHandleResponses
主體函數中response是通過ajaxHandleResponses來處理的:
// 得到響應數據 if ( responses ) { // 通過ajaxHandleResponses處理數據 response = ajaxHandleResponses( s, jqXHR, responses ); }
我們來看看該函數干了些什么。
function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes, responseFields = s.responseFields; // 將responseXXX填入jqXHR指定位置,也就是responseXML或者responseText // 其中jqXHR.xml對應responseXML,jqXHR.text對應responseText for ( type in responseFields ) { if ( type in responses ) { jqXHR[ responseFields[type] ] = responses[ type ]; } } // 刪除掉通配dataType,得到返回的Content-Type while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader("Content-Type" ); } } // 看看是不是我們能處理的Content-Type,比如圖片這類二進制類型就不好處理了 if ( ct ) { // 實際上能處理的就是text、xml和json for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { // 如果是這三種類型,則推入dataTypes里 dataTypes.unshift( type ); break ; } } } // 如果dataTypes是我們想要的,也就是text、xml、json if ( dataTypes[ 0 ] in responses ) { // 則最終dataType就是這個了 finalDataType = dataTypes[ 0 ]; // 否則 } else { // 嘗試轉換成我們要的dataType for ( type in responses ) { // 如果dataTypes[ 0 ]不存在,則直接用type作為最終dataType // 否則,看看能不能轉換,能的話就用type作為最終dataType if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0 ] ] ) { finalDataType = type; break ; } // 保存第一個type if ( ! firstDataType ) { firstDataType = type; } } // 用最終dataType或者用第一個type finalDataType = finalDataType || firstDataType; } // 如果有最終dataType if ( finalDataType ) { // 如果最終dataType不是dataTypes[ 0 ] if ( finalDataType !== dataTypes[ 0 ] ) { // 將finalDataType推入dataTypes隊列里 dataTypes.unshift( finalDataType ); } // 返回responses對應的finalDataType數據 return responses[ finalDataType ]; } }
?
jQuery.fn.load
實際上有兩個jQuery.fn.load,一個是類似于onload的方法,另一個則是載入指定html頁面。
前一個是jQuery.fn.on的簡單擴展,而后面一個則是使用jQuery.ajax方法的擴展。
jQuery.fn.load = function ( url, params, callback ) { // 如果url不是string,且_load存在 // 證明這是onload方法,則調用保存的_load方法 if ( typeof url !== "string" && _load ) { return _load.apply( this , arguments ); } var selector, type, response, self = this , off = url.indexOf(" " ); // 看看是不是載入指定元素,比如參數是'ajax/test.html #container' if ( off >= 0 ) { // 分隔出需要載入的元素 selector = url.slice( off, url.length ); // 分隔出真正的url url = url.slice( 0 , off ); } // 模擬重載 if ( jQuery.isFunction( params ) ) { // 如果是函數那么就當這個是回調函數 callback = params; params = undefined; // 如果參數是objects,那么定義type是POST } else if ( params && typeof params === "object" ) { type = "POST" ; } // 如果有需要修改的元素,開始請求 if ( self.length > 0 ) { jQuery.ajax({ url: url, // 如果type為undefined,那么就會缺省為GET方法 type: type, dataType: "html" , data: params // 完成后回調 }).done( function ( responseText ) { // 保存reponse response = arguments; // 對元素寫入html // 如果selector存在 self.html( selector ? // 先用一個div來存儲整個html頁面的DOM,在找到selector的相關html jQuery("<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : // 否則直接用responseText responseText ); // 如果回調函數存在,則回調 }).complete( callback && function ( jqXHR, status ) { self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); }); } return this ; };
?
jQuery.get & jQuery.post
這兩個方法實際上就是通過jQuery.ajax擴展而來的。
// 加上get和post方法 jQuery.each( [ "get", "post" ], function ( i, method ) { // jQuery.get或jQuery.post為 jQuery[ method ] = function ( url, data, callback, type ) { // 模擬重載 if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // 利用jQuery.ajax完成任務 return jQuery.ajax({ url: url, type: method, dataType: type, data: data, success: callback }); }; });
?
jQuery.getScript & jQuery.getJSON
jQuery.getScript和jQuery.getJSON則是由jQuery.get擴展而來的。
jQuery.getScript = function ( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); };
jQuery.getJSON = function ( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
