jQuery中attr() 和 prop() 方法对比

一直都在用 jQuery 1.8.3 的版本,没有尝试过 jQuery 1.9.0 的版本。

于是,开始调试代码,在 1.9.0 的版本中:

 代码如下 复制代码
<input type="checkbox" /> <script> $(function() {
        $('input').click(function() {
            $(this).attr('checked');
        });
    }); </script>

点击 checkbox,结果都是 undefined

而在 1.8.3 的版本中,结果是 checked 和 undefined

到这里,问题答案找到了,就是使用 attr() 方法的问题,于是查看官方文档, 才知道从 jQuery 1.6 开始新增了一个方法 prop(),但是一直都没有使用过。

从中文意思看,两者分别是获取/设置 attributes 和 properties 的方法,那么为什么还要增加 prop() 方法呢?

Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior.
因为在 jQuery 1.6 之前,使用 attr() 有时候会出现不一致的行为。

那么,什么时候使用attr(),什么时候使用prop()?

To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method.
根据官方的建议:具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled 使用prop(),其他的使用 attr()

到此,将 attr(‘checked’) 改成 prop(‘checked’) 即可修复提的 issues 了。

^_^

等等,貌似问题还没真正解决,为什么开头例子中 jQuery 1.8.3 和 1.9.0 使用 attr() 会有所区别呢?

想知道他们的区别,最好的办法还是看他们的源代码:

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() 和 prop() 的区别:

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

 代码如下 复制代码

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

ret =  elem.getAttribute( name );

很明显的看出来,使用的 DOM 的 API setAttribute() 和 getAttribute() 方法操作的属性元素节点。

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

 代码如下 复制代码
return ( elem[ name ] = value ); return elem[ name ];

可以理解为 document.getElementById(el)[name] = value,这是转化成 element 的一个属性。

对比调试 1.9.0 和 1.8.3 的 attr() 方法,发现两者的区别在于

hooks.get( elem, name ))
返回的值不一样,具体的实现:

1.8.3 中

 代码如下 复制代码

boolHook = {
    get: function( elem, name ) { // Align boolean attributes with corresponding properties // Fall back to attribute presence where some booleans are not supported var attrNode,
            property = jQuery.prop( elem, name ); return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
            name.toLowerCase() : undefined;
    }
}
1.9.0 中
boolHook = { get: function( elem, name ) { var // Use .prop to determine if this attribute is understood as boolean prop = jQuery.prop( elem, name ), // Fetch it accordingly attr = typeof prop === "boolean" && elem.getAttribute( name ),
            detail = typeof prop === "boolean" ?

                getSetInput && getSetAttribute ?
                    attr != null : // oldIE fabricates an empty string for missing boolean attributes // and conflates checked/selected into attroperties ruseDefault.test( name ) ?
                        elem[ jQuery.camelCase( "default-" + name ) ] :
                        !!attr : // fetch an attribute node for properties not recognized as boolean elem.getAttributeNode( name ); return detail && detail.value !== false ?
            name.toLowerCase() :
            undefined;
    }
}

由此可见,1.9.0 开始不建议使用 attr() 来对具有 true 和 false 两个属性的属性进行操作了。

那么我们的结论是:

具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled 使用prop(),其他的使用 attr(),具体见下表:

时间: 2024-09-20 01:07:49

jQuery中attr() 和 prop() 方法对比的相关文章

jQuery中attr和prop方法的区别

之前看网上对比两者的文章,更是列出一个表来区分什么标签下使用prop,什么标签下使用attr,原谅我是懒惰的人,最害怕要背的东西,所以只有自己想想办法了. 既然我们想知道他们两的区别,最好就看看他们的源代码,不要被代码长度所吓到,我们只看关键的几句: attr方法代码(jQuery版本1.8.3)  代码如下 复制代码 attr: function( elem, name, value, pass ) {     var ret, hooks, notxml,         nType = e

jquery中attr和prop的区别分析

 这篇文章主要介绍了jquery中attr和prop的区别分析的相关资料,需要的朋友可以参考下     在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: • 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. • 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. 上面的描述也许有点模糊,举几个例子就知道了.

jQuery中attr()与prop()函数用法实例详解(附用法区别)_jquery

本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名) //获取属性的值(取得第一个匹配元素的属性值.通过这个方法可以方便地从第一个匹配元素中获取一个属性的值.如果元素没有相应属性,则返回 undefined ) 2.

jquery中attr和prop的区别详解(非常完整)

关于它们两个的区别,网上的答案很多 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. 相比attr,prop是1.6.1才新出来的,两者从中文意思理解,都是获取/设置属性的方法(attributes和properties).只是,window或document中使用.attr()方法在jQuery1.6之前不能正常运行,因为window和document中不能有attributes.prop应运而生了.

jQuery中attr()和prop()在修改checked属性时的区别_jquery

在做复选框全选按钮的时候,出现了一个问题,使用语句$.attr('checked',true),将复选框的属性改为被选中,在chrome浏览器中第一次点击有效后面就不行了,IE8倒是没有问题. 百度了很久找到原因是HTML的属性分为attribute和property,暂且将后者称为特性. checked属性即分为attribute->checked,和property->true,false. 对于一个checkbox,若未定义checked="checked",aler

关于jQuery中.attr()和.prop()的问题探讨_jquery

话说写了几句代码在ie8上能正常运行,chrome和ff却不行,朋友说这就是RP啊,郁闷! 其实功能需求是这样的,两个radio:男和女,一个button:重置.启动页面默认选中男,在用户选择女之后又点击重置按钮,需要恢复到默认状态. 复制代码 代码如下: <input type="radio" id="hRdMale" checked="checked" name="sex" value="male"

jQuery中attr和prop的区别

  attribute(特性),是我们赋予某个事物的特质或对象,而attribute是我们通过设置HTML标签而给之赋予的特性, property(属性),是早已存在的不需要外界赋予的特质,property是DOM对象自身就拥有的属性.   在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: 对于HTML元素本身就带有的固有属性,在处理时,使用pro

jQuery获取attr()与prop()属性值的方法及区别介绍_jquery

今天在项目中使用<select></select>下拉菜单时,使用juery操作,使页面加载完菜单默认选中的值为2,我一开始的操作如下: <!--html部分--> <select> <option value="1">1</option> <option value="2">2</option> <option value="3">3&l

JQuery中attr方法和removeAttr方法用法实例

  本文实例讲述了JQuery中attr方法和removeAttr方法用法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: