上一篇文章 ,講解了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元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

