zoukankan      html  css  js  c++  java
  • jQuery serialize

    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 );
    };
  • 相关阅读:
    电子商务测试点总结
    pc 端 测试点总结
    web测试点总结
    Monkey脚本API
    Git 命令
    配置samba的流程
    scrapy使用指南
    链接
    顺序表总结
    python数据类型——字符串类型
  • 原文地址:https://www.cnblogs.com/justany/p/2870087.html
Copyright © 2011-2022 走看看