jQuery 中 attr() 和 prop() 方法的区别

  今天看jquery mobile API 时候发现jQuery的高版本加入了prop()方法,觉得它跟attr()作用差不多,于是就查了一下他们的区别。

 

  首先看一下jquery的源码比较一下:

1.8.3 attr():

attr: function( elem, name, value, pass ) {
    var ret, hooks, notxml,
        nType = elem.nodeType;

    // don't get/set attributes on text, comment and attribute nodes
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
        return;
    }

    if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
        return jQuery( elem )[ name ]( value );
    }

    // Fallback to prop when attributes are not supported
    if ( typeof elem.getAttribute === "undefined" ) {
        return jQuery.prop( elem, name, value );
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

    // All attributes are lowercase
    // Grab necessary hook if one is defined
    if ( notxml ) {
        name = name.toLowerCase();
        hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
    }

    if ( value !== undefined ) {

        if ( value === null ) {
            jQuery.removeAttr( elem, name );
            return;

        } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
            return ret;

        } else {
            elem.setAttribute( name, value + "" );
            return value;
        }

    } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
        return ret;

    } else {

        ret = elem.getAttribute( name );

        // Non-existent attributes return null, we normalize to undefined
        return ret === null ?
            undefined :
            ret;
    }
}

 

1.9.0 attr():

  attr: function( elem, name, value ) {
    var ret, hooks, notxml,
        nType = elem.nodeType;

    // don't get/set attributes on text, comment and attribute nodes
    if ( !elem || 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 );
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

    // All attributes are lowercase
    // Grab necessary hook if one is defined
    if ( notxml ) {
        name = name.toLowerCase();
        hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
    }

    if ( value !== undefined ) {

        if ( value === null ) {
            jQuery.removeAttr( elem, name );

        } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
            return ret;

        } else {
            elem.setAttribute( name, value + "" );
            return value;
        }

    } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
        return ret;

    } else {

        // In IE9+, Flash objects don't have .getAttribute (#12945)
        // Support: IE9+
        if ( typeof elem.getAttribute !== "undefined" ) {
            ret =  elem.getAttribute( name );
        }

        // Non-existent attributes return null, we normalize to undefined
        return ret == null ?
            undefined :
            ret;
    }
}

 

1.8.3 和 1.9.0 的 prop() 是一样的:

prop: function( elem, name, value ) {
    var ret, hooks, notxml,
        nType = elem.nodeType;

    // don't get/set properties on text, comment and attribute nodes
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
        return;
    }

    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );

    if ( notxml ) {
        // 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;

        } else {
            return ( elem[ name ] = value );
        }

    } else {
        if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
            return ret;

        } else {
            return elem[ name ];
        }
    }
}

 

attr() 里面,最关键的两行代码

elem.setAttribute( name, value + "" ); 

ret =  elem.getAttribute( name );

prop() 里面,最关键的两行代码

return ( elem[ name ] = value ); 

return elem[ name ];

看到这里,大家也就知道了prop()和attr()的区别就是getAtttribute()和[]的区别,这两项的区别就是[]只能操作固有属性,而getAtttribute()可以操作自定义属性。

也就是说

  • 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法。
  • 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法。

 

举两个例子:

<a href="http://www.baidu.com" target="_self" class="btn">百度</a>

 这个例子里<a>元素的DOM属性有“href、target和class",这些属性就是<a>元素本身就带有的属性,也是W3C标准里就包含有这几个属性,或者说在IDE里能够智能提示出的属性,这些就叫做固有属性。处理这些属性时,建议使用prop方法。

<a href="#" id="link1" action="delete">删除</a>

这个例子里<a>元素的DOM属性有“href、id和action”,很明显,前两个是固有属性,而后面一个“action”属性是我们自己自定义上去的,<a>元素本身是没有这个属性的。这种就是自定义的DOM属性。处理这些属性时,建议使用attr方法。使用prop方法取值和设置属性值时,都会返回undefined值。

 

再举一个例子:

<input id="chk1" type="checkbox" />是否可见
<input id="chk2" type="checkbox" checked="checked" />是否可见

像checkbox,radio和select这样的元素,选中属性对应“checked”和“selected”,这些也属于固有属性,因此需要使用prop方法去操作才能获得正确的结果。

$("#chk1").prop("checked") == false
$("#chk2").prop("checked") == true

如果上面使用attr方法,则会出现:

$("#chk1").attr("checked") == undefined
$("#chk2").attr("checked") == "checked"
posted @ 2015-11-30 22:01  很好玩  阅读(343)  评论(0编辑  收藏  举报