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 );
    };
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/justany/p/2870087.html
Copyright © 2011-2022 走看看