jQ的取值操作: val()
发布在# 菜鸟解读 jQuery #2014年6月4日view:8953
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

本篇介绍的是关于 $().val() 逻辑和修正操作
没什么跳跃性,小编把关于val的hooks整理到了一起

jQuery.fn.extend({
    val: function( value ) {
        var hooks, ret, isFunction,
            elem = this[0];
        if ( !arguments.length ) {
            if ( elem ) {
                // <input type="radio/checkbox" />
                // option select button
                hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
                if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
                    return ret;
                }
                ret = elem.value;
                // rReturn = /\r\n/g
                return typeof ret === "string" ?
                    ret.replace(rreturn, "") :
                    ret == null ? "" : ret;
            }
            return;
        }
        isFunction = jQuery.isFunction( value );
        return this.each(function( i ) {
            var self = jQuery(this), val;
            if ( this.nodeType !== 1 ) {
                return;
            }
            if ( isFunction ) {
                //如果传入的是函数,则调用函数,将返回值作为val进行后续处理
                val = value.call( this, i, self.val() );
            } else {
                val = value;
            }
            //null undefined 转为 空字符串
            if ( val == null ) {
                val = "";
            } else if ( typeof val === "number" ) {
                //变成字符串
                val += "";
            } else if ( jQuery.isArray( val ) ) {
                //遍历数组的每一项,然后对值进行 转字符串处理
                val = jQuery.map(val, function ( value ) {
                    return value == null ? "" : value + "";
                });
            }
            // <input type="radio/checkbox/text/" />
            // option select button
            hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
            // 优先调用hooks
            if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
                this.value = val;
            }
        });
    }
});
jQuery.extend({
    valHooks: {
        option: {
            //如果被设置过,则返回.value,否则返回.text
            get: function( elem ) {
                var val = elem.attributes.value; 
                return !val || val.specified ? elem.value : elem.text;
            }
        },
        select: {
            get: function( elem ) {
                var value, i, max, option,
                    index = elem.selectedIndex,
                    values = [],
                    //所有的 option 元素
                    options = elem.options,
                    //检查当前元素时多选还是单选
                    one = elem.type === "select-one";
                //没有选中内容时
                if ( index < 0 ) {
                    return null;
                }
                i = one ? index : 0;
                max = one ? index + 1 : options.length;
                // select-one: 3,4
                // select-multiple: 0,len
                for ( ; i < max; i++ ) {
                    option = options[ i ];
                    if(
                        //option是被选中的 
                        option.selected && 
                        //不被禁用的option
                        ( jQuery.support.optDisabled ? 
                          !option.disabled : 
                          option.getAttribute("disabled") === null 
                        ) &&
                        //不被禁用的optgroup元素中的option
                        (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode,"optgroup" ))
                    ){
                        //取出value值
                        value = jQuery( option ).val();
                        //如果是one模式,就直接返回value
                        if ( one ) {
                            return value;
                        }
                        values.push( value );
                    }
                }
                //Getting value with val() failed after reset form in ie6/ie7:
                if ( one && !values.length && options.length ){
                    return jQuery( options[ index ] ).val();
                }
                return values;
            },
            set: function( elem, value ) {
                var values = jQuery.makeArray( value );
                jQuery(elem).find("option").each(function() {
                    //遍历时 如果option的值在指定的数组当中,则
                    this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
                });
                //如果都没有值,则修改selectedIndex属性
                if ( !values.length ) {
                    elem.selectedIndex = -1;
                }
                return values;
            }
        }
    }
});

if ( !getSetAttribute ) {
    nodeHook = jQuery.valHooks.button = {
        get: function( elem, name ) {
            var ret;
            //取出属性节点
            ret = elem.getAttributeNode( name );
            // ( 节点存在 && ( name||id ? 节点值是否为空 : 节点是否被设置过 ) ) ? 节点值 : undefined ;
            // coords 是 图片热点区域的坐标属性,基本用不到
            return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
                ret.nodeValue :
                undefined;
        },
        set: function( elem, value, name ) {
            // 获取属性节点
            var ret = elem.getAttributeNode( name );
            if ( !ret ) {
                //如果不存在 则创建然后设置到元素上
                ret = document.createAttribute( name );
                elem.setAttributeNode( ret );
            }
            //修改值
            return ( ret.nodeValue = value + "" );
        }
    }
}
// Radios and checkboxes getter/setter
if ( !jQuery.support.checkOn ) {
    jQuery.each([ "radio", "checkbox" ], function() {
        jQuery.valHooks[ this ] = {
            get: function( elem ) {
                //当默认的元素的val值是空的时候返回修正的on
                return elem.getAttribute("value") === null ? "on" : elem.value;
            }
        };
    });
}
jQuery.each([ "radio", "checkbox" ], function() {
    jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
        set: function( elem, value ) {
            //如果是数组的话,则检测元素值是否在数据当中,在就设置即可,否则返回undefined会导致后续处理
            if ( jQuery.isArray( value ) ) {
                return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
            }
        }
    });
});

本篇就到这里,感谢您的阅读

欢迎留言:提问,交流,斧正

评论
发表评论
暂无评论
WRITTEN BY
前端狮子
JS前端开发工程师 :喜欢研究js,nodejs,html5; 希望结交更多朋友~
TA的新浪微博
PUBLISHED IN
# 菜鸟解读 jQuery #

本栏解读的jQ为1.7.2版本。 本人也是刚开始读起源码,在这里分享下成长的心得。 本人能力有限,也是接触JS不久的初学者,定会有不少解析不全不够明朗【甚至BUG】的地方, 希望各位牛牛多多留言斧正 感谢阅读 ps:由于工作不定时繁忙,本人也无法定期更新,但是会尽量抽时间学习,分享给大家

我的收藏