jQuery serialize模塊是對象數組序列化模塊。
首先我們先看一下《JavaScript高級程序設計》中的序列化函數,專門用于form參數序列化的。
?
serialize函數
function serialize(form){ var parts = [], field = null , i, len, j, optLen, option, optValue; for (i = 0, len = form.elements.length; i < len; i++ ){ field = form.elements[i]; switch (field.type){ case "select-one" : case "select-multiple" : if (field.name.length){ for (j = 0, optLen = field.options.length; j < optLen; j++ ){ option = field.options[j]; if (option.selected){ optValue = "" ; if (option.hasAttribute){ optValue = (option.hasAttribute("value")) ? option.value : ooption.text); } else { optValue = (option.attributes["value"].specified ? option.value : option.text); } parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue)); } } } case undefined: case "file" : case "submit" : case "reset" : case "button" : break ; case "radio" : case "checkbox" : if (! fied.checked){ break ; } default : if (field.name.length){ parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value)); } } } return parts.join("&" ); } }
這能幫我們理解下面有些操作,當然從整體實現是差不多的。
但是jQuery提供了利用遞歸將深入對象或數組內部去序列化,而該方法只能對其下一級序列化,不能再深入下去。
而且jQuery能對滿足要求對象、數組進行序列化。
?
jQuery.param
jQuery.param = function ( a, traditional ) { var prefix, s = [], // 內部函數充填函數 add = function ( key, value ) { // 如果value是一個函數,運行并得到其值 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); // 向數組s中推入字符串"key=value" s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); }; // 如果traditional為true,提供jQuery1.3.2以下版本兼容處理 // 如果traditional沒定義 if ( traditional === undefined ) { // 將traditional設置成jQuery.ajaxSettings.traditional traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; } // 如果a數組,假設其是一個包含元素的數組 if ( jQuery.isArray( a ) || ( a.jquery && ! jQuery.isPlainObject( a ) ) ) { // Serialize the form elements // 對a中所有元素的name和value推入s數組 jQuery.each( a, function () { add( this .name, this .value ); }); // 否則 } else { // 如果是traditional方式,則以老的方式encode(jQuery1.3.2以下版本) // 否則遞歸encode for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // 將s數組用&連接成字符串,將空白替換成+ return s.join( "&" ).replace( r20, "+" ); };
jQuery.param能將所有參數序列化,提供了對jQuery1.3.2一下版本不深入對象內部的兼容模式。
?
buildParams函數
function buildParams( prefix, obj, traditional, add ) { var name; // 如果obj是一個數組 if ( jQuery.isArray( obj ) ) { // 序列化數組所有元素 jQuery.each( obj, function ( i, v ) { // 如果tranditional為true,或者prefix即當前obj名字為xxx[] if ( traditional || rbracket.test( prefix ) ) { // 則v可當成常量直接推入 add( prefix, v ); // 否則,即prefix不是xxx[]形式,可能會xxx或者xxx[i]形式 } else { // v不是常量(是數組或者對象),如果v此時不是數組或則對象,則下次可以當成是常量了,即變成xxx[] // 否則變成xxx[i],遞歸 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]" , v, traditional, add ); } }); // 否則,非tranditional且obj是對象 } else if ( !traditional && jQuery.type( obj ) === "object" ) { // 遍歷序列化 for ( name in obj ) { // 遞歸,變成xxx[name] buildParams( prefix + "[" + name + "]" , obj[ name ], traditional, add ); } } else { // 到這里,證明不是對象也不是數組,或者是traditional模式,那么直接添加吧 add( prefix, obj ); } };
如果是傳統模式,則不遞歸,直接輸出,否則遞歸。?
?
jQuery.fn.serialize
jQuery.fn.serialize = function () { // 利用jQuery.param和jQuery.fn.serializeArray return jQuery.param( this .serializeArray() ); };
序列化函數,實際上是調用param來序列化。
不過先要用serializeArray組裝一下。?
?
jQuery.fn.serializeArray
jQuery.fn.serializeArray: function () { // 使用jQuery.fn.map遍歷所有元素 return this .map( function (){ // 讀取this.elements var elements = jQuery.prop( this , "elements" ); // 如果elements存在則變成數組返回,否則返回this return elements ? jQuery.makeArray( elements ) : this ; }) // 過濾 .filter( function (){ // 得到type var type = this .type; // Use .is(":disabled") so that fieldset[disabled] works // 如果該元素有name屬性,并且這個元素不是:disabled return this .name && !jQuery( this ).is( ":disabled" ) && // 如果節點名字是input、select、textarea或者keygen, // 并且type不是submit、button、image或reset這些可提交元素 rsubmittable.test( this .nodeName ) && !rsubmitterTypes.test( type ) && // 如果this.checked為true,或者不是checkbox、radio ( this .checked || ! manipulation_rcheckableType.test( type ) ); // 滿足的保留,否則過濾 }) // 再次map遍歷所有剩下元素 .map( function ( i, elem ){ // 通過.val獲取elem的值 var val = jQuery( this ).val(); // 如果val為null return val == null ? // 則返回null null : // 否則如果是數組 jQuery.isArray( val ) ? // 遍歷數組的子元素 jQuery.map( val, function ( val ){ // 組裝成下面形式的元素組成的數組 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; }) : // 返回這種形式 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; }).get(); // 轉成數組返回,此時不能鏈式了 };
?組裝參數對象,并過濾掉一些不需要序列化的元素。
?
jQuery.fn.map
jQuery.fn.map = function ( callback ) { return this .pushStack( jQuery.map( this , function ( elem, i ) { return callback.call( elem, i, elem ); })); };
我們可以看出其主要使用了jQuery.map來實現的。
?
jQuery.map
jQuery.map = function ( elems, callback, arg ) { var value, i = 0 , length = elems.length, isArray = isArraylike( elems ), ret = []; // 先看看elems是不是數組 if ( isArray ) { // 遍歷數組 for ( ; i < length; i++ ) { // 得到callback的返回值 value = callback( elems[ i ], i, arg ); // 組裝返回值數組 if ( value != null ) { ret[ ret.length ] = value; } } // 如果不是數組,那么就當他是一個對象 } else { // 遍歷其所有key for ( i in elems ) { // 得到callback的返回值 value = callback( elems[ i ], i, arg ); // 組裝返回值數組 if ( value != null ) { ret[ ret.length ] = value; } } } // 合并所有嵌套數組 return core_concat.apply( [], ret ); };
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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