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

