zoukankan      html  css  js  c++  java
  • jQuery .attr() vs. .prop()

    Property vs. Attribute

    在开始正式比较prop()和attr()两个jQuery方法之前,我们有必要先弄清一下Property和Attribute两个单词的意思。在中文里面,它们都是属性的意思,那究竟有什么区别呢?我是这么理解的(曾经在《深入浅出WPF》一书中看到过一些关于XAML相关的解释,觉得这里也是适用的):

    Property - 属性、字段,这是站在面向对象的层面去理解的,当我们将现实中的某一物体用代码把它抽象出来时,那么它的属性我们就用Property来表示。在这里我们要研究的其实是DOM 元素,例如 input checkbox,它就是现实中的一个复选框,那么Javascript描述它时就赋予了它很多属性,id表示它的唯一标识,type表示它的类别,checked表示它的状态等等,我们就称这些为Property。

    Attribute - 特性,更多的我将它称为特性。这是站在编译的层面去理解它的,我们知道HTML它是一种标记语言,什么意思,就是一个标签最后会被编译器编译为一个DOM对象

    <input type="checkbox" id="chk1" class="sampleclass">

    会被编译为一个DOM Element,而这里的type,id我们就称之为Attribute,你会发现这里的AttributeName和上面提到的PropertyName有些会同名,没错,它们用来初始化DOM对象的一些属性,假设被编译出的对象是elem,那么elem.type就是checkbox,elem.id就是chk1,所有在我看来,Attribute其实是给编译器看的。Attribute名称不一定都是和Property一一对应的,例如Attribute的class <–> Property的classname,这些不是我们关心的,只要编译器知道其中的对应关系就行了。当然,正所谓特性,肯定还可以定义一些特有的性质,例如在标签中我可以自定义一些Attribute

    <input type="checkbox" id="chk1" customizedattr="my attribute" >

    在理解了这两个单词的区别之后,在我看来,理想状态下,基本都可以用prop()搞定,除了需要去获取一些自定义的Attribute那就得让attr()出山了。

    操作DOM元素Property和Attribute

    作为一个对象的属性,按照惯例我们当然可以通过 object.PropertyName的方式来get/set:

    var proValue = object.PropertyName;
    object.PropertyName = newProValue;

    或者

    var pValue = object["PropertyName"];
    object["PropertyName"] = newValue;

    返回值可以是Object类型,返回undefined如果不存在指定的属性名称,

    同样,newProValue也可以是一个Object

     

    而作为对象的特性,经过编译器编译后所有的特性会被存放在一个叫attributes的属性下面,这个属性的类型是NamedNodeMap,如下图所示。

    Javascript提供两个方法来进行set/get:

    var attrValue = object.getAttribute("AttributeName");
    object.setAttribute("AttributeName", newAttrValue);

    返回值和newAttrValue都只是string类型,返回null如果不存在指定的特性名称。

     

    jQuery .attr()

    如果理解了Property和Attribute的区别以及Javascript的原生操作DOM元素的Attribute的方法的话,那这个.attr()也就不难理解了,jQuery就是把原生的Javascript方法包装一下,提高了跨浏览器的兼容性以及易用性,具体使用方法的话还是参考.attr() api。当然个人还是建议,在.prop()能搞定的地方就不用.attr(),目前能想到的情况:

    • jQuery 版本 < 1.6

    • 需要设置/获取自定义的特性

    jQuery .prop()

    根据 John Resig 本人博客所建议,优先选择.prop(),具体使用方法参考.prop() api,原因主要两点:

    • 更合理,更简单

    • 性能稍稍优于.attr()

    测试

    <div><input type="checkbox" id="chk1" regVal="Test" dataTT="dataTest" myvalue="MyTestValue"><label for="chk1">Monday</label></div>
    $(document).ready(function(){
    $("input[type=checkbox]").click(function(index){
    var domElem = this;
    var $Elem = $(this);
    
    $("#resultContainer").append("<pre>domElem["class"]                                           " + domElem["class"] + "</pre>");
    $("#resultContainer").append("<pre>domElem["className"]                                       " + domElem["className"] + "</pre>");
    $("#resultContainer").append("<pre>domElem.class                                              " + domElem.class + "</pre>");
    $("#resultContainer").append("<pre>domElem.className                                          " + domElem.className + "</pre>");
    $("#resultContainer").append("<pre>domElem.getAttribute("class")                              " + domElem.getAttribute("class") + "</pre>");
    $("#resultContainer").append("<pre>domElem.getAttribute("className")                          " + domElem.getAttribute("className") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.attr("class")                                        " + $Elem.attr("class") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.attr("className")                                    " + $Elem.attr("className") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.prop("class")                                        " + $Elem.prop("class") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.prop("className")                                    " + $Elem.prop("className") + "</pre>");
    
    $("#resultContainer").append("<pre>*************************************************************************************************************</pre>");
    
    $("#resultContainer").append("<pre>domElem["myvalue"]                                           " + domElem["myvalue"] + "</pre>");
    $("#resultContainer").append("<pre>domElem.myvalue                                              " + domElem.myvalue + "</pre>");
    $("#resultContainer").append("<pre>domElem.getAttribute("myvalue")                              " + domElem.getAttribute("myvalue") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.attr("myvalue")                                        " + $Elem.attr("myvalue") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.prop("myvalue")                                        " + $Elem.prop("myvalue") + "</pre>");
    
    $("#resultContainer").append("<pre>*************************************************************************************************************</pre>");
    
    $("#resultContainer").append("<pre>domElem["checked"]                                           " + domElem["checked"] + "</pre>");
    $("#resultContainer").append("<pre>domElem.checked                                              " + domElem.checked + "</pre>");
    $("#resultContainer").append("<pre>domElem.getAttribute("checked")                              " + domElem.getAttribute("checked") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.attr("checked")                                        " + $Elem.attr("checked") + "</pre>");
    $("#resultContainer").append("<pre>$Elem.prop("checked")                                        " + $Elem.prop("checked") + "</pre>");
    
    $("#resultContainer").append("<pre>*************************************************************************************************************</pre>");
    
    var inputElem = $("input[type=text]")[0];
    var $inputElem = $(inputElem);
    $("#resultContainer").append("<pre>inputElem["value"]                                           " + inputElem["value"] + "</pre>");
    $("#resultContainer").append("<pre>inputElem.value                                              " + inputElem.value + "</pre>");
    $("#resultContainer").append("<pre>inputElem.getAttribute("value")                              " + inputElem.getAttribute("value") + "</pre>");
    $("#resultContainer").append("<pre>$inputElem.attr("value")                                        " + $inputElem.attr("value") + "</pre>");
    $("#resultContainer").append("<pre>$inputElem.prop("value")                                        " + $inputElem.prop("value") + "</pre>");
    });
    });

    Results:

    小结

    .attr()和.prop()两个jQuery方法其实都是对Javascript原生方法elem.getAttribute()/elemsetAsttribute()和elem.PropertyName|elem[“PropertyName”]的包装,以支持更好地兼容性和易用性。对于如何选择,jQuery 1.6+的版本中,操作DOM元素的属性时用prop(),操作特性时用attr(),属性和特性若有重叠时,优先使用prop(),例如:id,type,classname等等;对于那些动态的属性,使用prop(),例如:input checkbox 的checked属性,input select 的selected属性,input text 的value属性(这个也推荐使用.val()方法);对于那些自定义的特性,使用attr()。

    参考

  • 相关阅读:
    人员考勤,MySQL数据库一个表自动生成3表筛选人员迟到早退缺勤
    Thinkphp中js报错,Uncaught SyntaxError: Unexpected token }
    Invalid ON UPDATE clause for 'create_date' column
    mysql创建某个数据库中的某张表 只读用户
    iOS开发 iOS9横屏后状态栏隐藏处理
    iOS开发 个别页面是否支持页面旋转
    iOS开发 点击某处横屏竖屏切换
    iOS开发 QQ粘性动画效果
    iOS开发 贝塞尔曲线
    iOS开发 获取状态栏的点击事件
  • 原文地址:https://www.cnblogs.com/seanshao/p/5727471.html
Copyright © 2011-2022 走看看