jQuery的attr方法和prop方法使用区别

jQuery的attr方法和prop方法使用区别

在一次面试中,被问到这样一个问题:

 <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <input type="text"  id="inn" value="100" />
        <script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            document.getElementById("inn").value="1000";
            $("#inn").attr("value")//结果是多少? 
        </script>
    </body>
</html>

通过js来改变value的值1000,我们在界面上看到的值也是改变了,但实际是$(“#inn”).attr(“value”)还是100.

我们都知道attr是attribute缩写,prop是property的缩写,字面意思都是指属性。具体的区别可能分的不是很清楚。在经历此次面试之后我又看了一下jQuery的源代码(jQuery版本3.3.1)。

Attr 方法源码


$.fn.attr = function( name, value ) {
        return access( this, jQuery.attr, name, value, arguments.length > 1 );
    }
jQuery.attr = $.attr = function( elem, name, value ) {

        var ret, hooks,
            nType = elem.nodeType;
        // Don't get/set attributes on text, comment and attribute nodes
        if ( nType === 3 || nType === 8 || nType === 2 ) {
            return;
        }
        // Fallback to prop when attributes are not supported
        if ( typeof elem.getAttribute === "undefined" ) {
            return jQuery.prop( elem, name, value );
        }
        // Attribute hooks are determined by the lowercase version
        // Grab necessary hook if one is defined
        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
            hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
                ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
        }
        if ( value !== undefined ) {
            if ( value === null ) {
                jQuery.removeAttr( elem, name );
                return;
            }
            if ( hooks && "set" in hooks &&
                ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                return ret;
            }
            elem.setAttribute( name, value + "" );
            return value;
        }
        if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
            return ret;
        }
        ret = jQuery.find.attr( elem, name );
        // Non-existent attributes return null, we normalize to undefined
        return ret == null ? undefined : ret;
    }

    jQuery.find.attr = Sizzle.attr = function( elem, name ) {

    // Set document vars if needed
    if ( ( elem.ownerDocument || elem ) !== document ) {
        setDocument( elem );
    }
    var fn = Expr.attrHandle[ name.toLowerCase() ],
        // Don't get fooled by Object.prototype properties (jQuery #13807)
        val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
            fn( elem, name, !documentIsHTML ) :
            undefined;
    return val !== undefined ?
        val :
        support.attributes || !documentIsHTML ?
            elem.getAttribute( name ) :
            (val = elem.getAttributeNode(name)) && val.specified ?
                val.value :
                null;
}

Prop方法源码

$.fn.prop = function( name, value ) {
        return access( this, jQuery.prop, name, value, arguments.length > 1 );
    },
prop: function( elem, name, value ) {
        var ret, hooks,
            nType = elem.nodeType;
        // Don't get/set properties on text, comment and attribute nodes
        if ( nType === 3 || nType === 8 || nType === 2 ) {
            return;
        }
        if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
            // Fix name and attach hooks
            name = jQuery.propFix[ name ] || name;
            hooks = jQuery.propHooks[ name ];
        }
        if ( value !== undefined ) {
            if ( hooks && "set" in hooks &&
                ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
                return ret;
            }
            return ( elem[ name ] = value );
        }
        if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
            return ret;
        }
        return elem[ name ];
    }

jQuery.fn.attr方法和 jQuery.fn.prop方法源码共同调用公共方法 access

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function
var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
    var i = 0,
        len = elems.length,
        bulk = key == null;
    // Sets many values  设置多个值$.fn.attr({'width':'50px','height':'50px'})
    if ( toType( key ) === "object" ) {
        chainable = true;
        for ( i in key ) {
            access( elems, fn, i, key[ i ], true, emptyGet, raw );
        }
    // Sets one value  设置一个值$.fn.attr('width','50px')
    } else if ( value !== undefined ) {
        chainable = true;
        if ( !isFunction( value ) ) {
            raw = true;
        }
        if ( bulk ) {
            // Bulk operations run against the entire set
            if ( raw ) {
                fn.call( elems, value );
                fn = null;
            // ...except when executing function values
            } else {
                bulk = fn;
                fn = function( elem, key, value ) {
                    return bulk.call( jQuery( elem ), value );
                };
            }
        }
        if ( fn ) {
            for ( ; i < len; i++ ) {
                fn(elems[ i ], key, raw ?
                    value :
                    value.call( elems[ i ], i, fn( elems[ i ], key ) )
                );
            }
        }
    }
    if ( chainable ) {return elems;}
    // Gets
    if ( bulk ) {return fn.call( elems );}
    return len ? fn( elems[ 0 ], key ) : emptyGet;
};

从源代码中可以看到attr方法中获取属性是通过ele.getAttribute去获取对应的属性值 即获取dom文档节点的属性,而prop方法是通过是通过ele[name]或者ele.name来获取属性值 即获取dom文档节点对应的js对象的属性。dom文档节点与dom节点对应的js对象是相同,一个发生变化另一个随之而变。在浏览器通过jQuery获取input查看各个对应的js属性,我们可以看到元素对应的js对象属性(下图)
这里写图片描述
这里写图片描述

我只截取部分需要的属性值,有需要的各位可以自己在浏览器查看。
对应的文档节点属性我们可以在浏览器端的控制台的Elements查看到。
这里写图片描述

通过attr方法添加的属性我们都可在浏览器的Elements查看到,通过prop添加的属性,无法直接在对应的文档节点上看到,只能通过获取到文档节点对应的js对象来查看获取

   $("#inn").attr('self-attr','selfAttr');//下图第一张的结果释义
   $("#inn").prop('self-prop','selfProp');//下图第二张的结果释义

attr
prop


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值