查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!
上一篇文章,讲授了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" ); }
文章结束给大家分享下程序员的一些笑话语录: 程序员打油诗
写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱。
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年。
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员。
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员。