提问



所以jQuery 1.6具有新功能prop()[163] [164]


$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})


或者在这种情况下,他们做同样的事情?


如果我做必须切换到使用prop(),如果我切换到1.6,所有旧的attr()调用将会中断?


更新




selector = '#id'

$(selector).click(function() {
    //instead of:
    var getAtt = this.getAttribute('style');
    //do i use:
    var thisProp = $(this).prop('style');
    //or:
    var thisAttr = $(this).attr('style');

    console.log(getAtt, thisProp, thisAttr);
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id='id' style="color: red;background: orange;">test</div>



2012年11月1日更新


我的原始答案特别适用于jQuery 1.6。我的建议保持不变,但jQuery 1.6.1略有改变:面对预测的一堆破碎的网站,jQuery团队将attr()恢复到接近(但不完全相同)的旧行为。布尔属性。 John Resig也在博客上写了这篇文章。我可以看到他们所处的困难,但仍然不同意偏好attr()的建议。[165] [166]


原始回答


如果您只使用过jQuery而不是直接使用DOM,那么这可能是一个令人困惑的变化,尽管它在概念上肯定是一种改进。对于使用jQuery的网站而言,由于这种变化而破坏不太好。


我将总结主要问题:



  • 您通常需要prop()而不是attr()

  • 在大多数情况下,prop()attr()过去做的事情。在代码中用prop()替换attr()的调用通常会有效。

  • 属性通常比属性更容易处理。属性值可以只是一个字符串,而属性可以是任何类型。例如,checked属性是布尔值,style属性是每个样式具有单独属性的对象,size属性是数字。

  • 如果属性和具有相同名称的属性都存在,通常更新一个将更新另一个,但输入的某些属性不是这种情况,例如valuechecked:对于这些属性,属性始终表示当前状态,而属性(旧版本的IE除外)对应于输入的默认值/检查(反映在defaultValue/defaultChecked属性中)。

  • 此更改删除了一些在属性和属性前面停留的魔法jQuery层,这意味着jQuery开发人员必须了解属性和属性之间的差异。这是件好事。



如果你是一个jQuery开发人员,并且对整个业务的属性和属性感到困惑,那么你需要退一步学习一点,因为jQuery不再那么努力地保护你不受这些东西的影响。关于这个主题的权威但有点干的话,有规格:DOM4,HTML DOM,DOM Level 2,DOM Level 3. Mozilla的DOM文档对大多数现代浏览器都有效,并且比规范更容易阅读,所以你可能会发现他们的DOM参考有用。有一个关于元素属性的部分。[167] [168] [169] [170] [171] [172]


作为属性如何比属性更易于处理的示例,请考虑最初检查的复选框。以下是两个可能的有效HTML片段:


<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">


那么,你怎么知道是否用jQuery检查了复选框?看看Stack Overflow,你会发现以下建议:



  • if ( $("#cb").attr("checked") === true ) {...}

  • if ( $("#cb").attr("checked") == "checked" ) {...}

  • if ( $("#cb").is(":checked") ) {...}



对于checked布尔属性来说,这实际上是世界上最简单的事情,自1995年以来,该属性在每个主要的可编写脚本的浏览器中都存在并且完美无缺:


if (document.getElementById("cb").checked) {...}


该属性还可以检查或取消选中复选框:


document.getElementById("cb").checked = false


在jQuery 1.6中,这毫不含糊地变成了


$("#cb").prop("checked", false)


使用checked属性编写复选框脚本的想法是无益的,也是不必要的。该物业是您所需要的。



  • 检查或取消选中复选框的正确方法是使用checked属性
  • 并不明显
  • 属性值反映默认值而不是当前可见状态(除了IE的某些旧版本,因此使事情变得更加困难)。该属性不会告诉您是否选中了页面上的复选框。见http://jsfiddle.net/VktA6/49/。


最佳参考


我认为蒂姆说得很好,但让我们退后一步:[173]


DOM元素是一个对象,一个在内存中的东西。与OOP中的大多数对象一样,它具有属性。它还单独包含元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。某些元素的属性从属性获取具有相同或相似名称的初始值(value获取其初始值来自value属性; href从href属性获取其初始值,但它与class属性的值不完全相同; className。其他属性以其他方式获取其初始值:例如,parentNode属性根据其父元素获取其值;元素始终具有style属性,无论它是否具有样式属性。


让我们在http://example.com/testing.html的页面中考虑这个锚点:


<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>


一些无偿的ASCII艺术(并遗漏了很多东西):


+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
|             HTMLAnchorElement             |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| href:       "http://example.com/foo.html" |
| name:       "fooAnchor"                   |
| id:         "fooAnchor"                   |
| className:  "test one"                    |
| attributes:                               |
|    href:  "foo.html"                      |
|    name:  "fooAnchor"                     |
|    id:    "fooAnchor"                     |
|    class: "test one"                      |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+


请注意,属性和属性是不同的。


现在,尽管它们是截然不同的,因为所有这些都是从头开始设计的,而不是从头开始设计,如果你设置它们,许多属性会回写它们派生的属性。但并非所有人都这样做,正如你从上面的href中看到的那样,映射并不总是直接的传递价值,有时会涉及到解释。


当我谈到属性是对象的属性时,我不是在抽象地说。这里是一些非jQuery代码:


var link = document.getElementById('fooAnchor');
alert(link.href);                 // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"


(这些值与大多数浏览器一样;有一些变化。)


link对象是真实的,您可以看到在它上面访问属性和访问属性之间存在真正的区别。


正如Tim所说,绝大多数当时,我们希望与属性合作。部分原因是因为它们的值(甚至是它们的名称)在浏览器中更加一致。我们大多只希望在没有与之相关的属性(自定义属性)时使用属性,或者当我们知道该特定属性时,属性和属性不是1:1(与上面的href和href一样)。


标准属性在各种DOM规范中列出:



  • DOM2 HTML (很大程度上已过时,请参阅HTML规范)

  • DOM2 Core (已废弃)

  • DOM3 Core (已废弃)

  • DOM4



这些规格有很好的索引,我建议保持链接方便;我一直都在使用它们。[175] [176] [177] [178] [179]


例如,自定义属性将包括您可能放置在元素上的任何data-xyz属性,以便为您的代码提供元数据(现在,只要您坚持data-,这就是HTML5的有效性) (前缀)。(jQuery的最新版本允许您通过data函数访问data-xyz元素,但该函数只是data-xyz属性的访问者[[它做得越来越少]];除非你真的需要它的功能,否则我会使用attr函数与data-xyz属性进行交互。)


attr函数曾经有一些复杂的逻辑来获得他们想要的东西,而不是字面上得到属性。它混淆了这些概念。转移到propattr意味着将它们去混合。简言之,在v1.6.0中,jQuery在这方面走得太远,但功能很快被添加回attr以处理人们使用attr的常见情况,从技术上来说应该使用prop。[[[180]

其它参考1


jQuery已经有很长一段时间了。多年来,他们一直满足于一个名为attr()的函数,它主要检索DOM属性,而不是你期望从名称中得到的结果。 attr()prop()的隔离应该有助于缓解HTML属性和DOM属性之间的一些混淆。 $.fn.prop()获取指定的DOM属性,而$.fn.attr()获取指定的HTML属性。[181] [182]


为了完全理解它们是如何工作的,这里是对HTML属性和DOM属性之间差异的扩展解释:


HTML属性



语法:



<body onload="foo()">


目的:
允许标记具有与其关联的数据以用于事件,呈现和其他目的。


可视化:

class属性显示在正文中。它可以通过以下代码访问:


var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");


属性以字符串形式返回,并且从浏览器到浏览器可能不一致。但是,它们在某些情况下至关重要。如上所示,IE 8 Quirks Mode(及以下)需要get/set/removeAttribute中DOM属性的名称而不是属性名称。这是了解差异的重要原因之一。


DOM属性



语法:



document.body.onload = foo;


目的:
提供对属于元素节点的属性的访问。这些属性与属性类似,但只能通过JavaScript访问。这是一个重要的区别,有助于阐明DOM属性的作用。 请注意,属性与属性完全不同,因为此事件处理程序分配无用且无法接收事件(正文没有onload事件,只有onload属性)。


可视化:



在这里,你会注意到Firebug中DOM选项卡下的属性列表。这些是DOM属性。你会立即注意到它们中的一些,因为你以前会在不知情的情况下使用它们。它们的值是你将通过JavaScript接收什么。


文档




  • JavaScript:The Definitive Guide by
    大卫弗拉纳根

  • HTML属性,
    Mozilla开发中心

  • DOM元素属性,Mozilla开发中心



实施例



HTML:<textarea id="test" value="foo"></textarea> [183]​​]] [184] [185]


JavaScript:alert($('#test').attr('value'));


在早期版本的jQuery中,这将返回一个空字符串。在1.6中,它返回适当的值,foo


在没有浏览任何一个函数的新代码的情况下,我可以充满信心地说,混淆更多地与HTML属性和DOM属性之间的差异有关,而不是与代码本身有关。希望这能为你解决一些问题。


-Matt

其它参考2


属性在DOM中; HTML中的属性被解析为DOM。


更多细节



如果更改属性,则更改将反映在DOM中(有时使用不同的名称)。


示例:更改标记的class属性将更改DOM中该标记的className属性。
如果标记上没有属性,则仍具有相应的DOM属性,其属性为空或默认值。


示例:当您的标记没有class属性时,DOM属性className确实存在空字符串值。


修改


如果更改一个,另一个将由控制器更改,反之亦然。
这个控制器不在jQuery中,而是在浏览器的本机代码中。

其它参考3


只是HTML属性和DOM对象之间的区别导致了混淆。对于那些能够很好地处理DOM元素的本地属性,如this.src this.value this.checked等,[[.prop是对家庭的热烈欢迎。对于其他人来说,这只是一层混乱。让我们清楚一点。


查看.attr.prop之间差异的最简单方法是以下示例:


<input blah="hello">



  1. $('input').attr('blah') :按预期返回'hello'。这里没有意外。

  2. $('input').prop('blah') :返回undefined - 因为它试图[HTMLInputElement].blah - 并且该DOM对象上没有这样的属性。只有它作为该元素的属性存在于范围内,即[HTMLInputElement].getAttribute('blah')



现在我们改变一些事情:


$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');



  1. $('input').attr('blah') :返回'apple'嗯?为什么不在这个元素上设置梨。因为属性是在输入属性上更改的,而不是DOM输入元素本身 - 它们基本上几乎彼此独立工作。

  2. $('input').prop('blah') :返回'pear'



出于上述原因,你真正需要注意的是不要在整个应用程序中混用这些属性用于同一属性


看一个证明差异的小提琴: http://jsfiddle.net/garreh/uLQXc/[186]





.attr vs .prop:



第1轮:风格



<input style="font:arial;"/>



  • .attr('style') - 返回匹配元素的内联样式,即"font:arial;"

  • .prop('style') - 返回样式声明对象,即CSSStyleDeclaration



第2轮:值



<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');



  • .attr('value') - 返回'hello' *

  • .prop('value') - 返回'i changed the value'



*注意:jQuery因此有一个.val()方法,内部相当于.prop('value')

其它参考4


TL; DR


在大多数情况下,使用prop()而不是attr()


属性是输入元素的当前状态。 属性是默认值。


属性可以包含不同类型的东西。属性只能包含字符串

其它参考5


一切都在文档中:



  在特定情况下,属性和属性之间的差异可能很重要。在jQuery 1.6之前,.attr()方法有时在检索某些属性时会考虑属性值,这可能会导致行为不一致。从jQuery 1.6开始,.prop()方法提供了一种显式检索属性值的方法,而.attr()只检索属性。



所以使用道具!

其它参考6


脏检查是差异可观察的示例。[187]


要查看它,请运行以下代码段并:



  • 点击按钮。两个复选框都已经过检查。

  • 取消选中这两个复选框。

  • 再次点击该按钮。仅选中了prop复选框。 BANG!





$('button').on('click', function() {
  $('#attr').attr('checked', 'checked')
  $('#prop').prop('checked', true)
})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>attr <input id="attr" type="checkbox"></label>
<label>prop <input id="prop" type="checkbox"></label>
<button type="button">Set checked attr and prop.</button>



属性位于HTML 文本文档/文件中(==想象这是解析html标记的结果),而


属性位于HTML DOM树中(==基本上是JS意义上某个对象的实际属性)。


重要的是,它们中的许多都是同步的(如果更新class属性,html中的class属性也将被更新;否则)。 某些属性可能会同步到意外的属性 - 例如,属性 checked对应属性 defaultChecked,因此



  • 手动选中复选框将更改.prop('checked')值,但不会更改.attr('checked').prop('defaultChecked')

  • 设置$('#input').prop('defaultChecked', true)也会改变.attr('checked'),但这在元素上不可见。




  经验法则:.prop()方法应该用于布尔属性/属性以及html中不存在的属性
  (例如window.location)。所有其他属性(你可以看到的属性)
  html)可以而且应该继续用.attr()来操纵
  方法。 (http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/)[188]



这里有一个表格,显示.prop()的首选位置(尽管仍然可以使用.attr())。







为什么有时候你会想要使用.prop()代替.attr(),后者是官方建议的?




  1. .prop()可以返回任何类型 - 字符串,整数,布尔值;而.attr()总是返回一个字符串。

  2. 据说
  3. .prop().attr()快约2.5倍。


其它参考7


.attr():



  • 获取匹配元素集中第一个元素的属性的值。

  • 为您提供元素的值,因为它是在页面加载中的html中定义的



.prop():



  • 获取匹配元素集中第一个元素的属性的值。

  • 提供通过javascript/jquery
  • 修改的元素的更新值

其它参考8


通常你会想要使用属性。
仅将属性用于:



  1. 获取自定义HTML属性(因为它未与DOM属性同步)。

  2. 获取不与DOM属性同步的HTML属性,例如获取标准HTML属性的原始值,如<input value="abc">.


其它参考9


attributes - > HTML


properties - > DOM

其它参考10


在jQuery 1.6之前,attr()方法 有时 在检索属性时会考虑属性值,这会导致相当不一致的行为。


prop()方法的引入提供了一种显式检索属性值的方法,而.attr()检索属性。


文件:


jQuery.attr()
获取匹配元素集中第一个元素的属性值。


jQuery.prop()
获取匹配元素集中第一个元素的属性值。

其它参考11


轻轻提醒一下使用prop(),例如:


if ($("#checkbox1").prop('checked')) {
    isDelete = 1;
} else {
    isDelete = 0;
}


上面的函数用于检查checkbox1是否被选中,如果选中:return 1;如果不是:返回0.函数prop()在这里用作GET函数。


if ($("#checkbox1").prop('checked', true)) {
    isDelete = 1;
} else {
    isDelete = 0;
}


上面的函数用于设置要检查的checkbox1并始终返回1.现在函数prop()用作SET函数。


不要搞砸。


P/S:当我检查图像 src 属性时。如果 src 为空, prop 返回页面的当前URL(错误), attr 返回空字符串(右)。

其它参考12



  1)属性在DOM中; HTML中的属性是
  解析成DOM。

  
  2)$(elem).attr(checked)(1.6.1+)checked(String)Will
  用复选框状态更改

  
  3)$(elem).attr(checked)(pre-1.6)true(布尔值)已更改
  与复选框状态




  • 我们通常希望使用DOM对象而不是自定义属性
    喜欢data-img, data-xyz

  • 访问checkbox值和href时也有一些区别
    随着attr()prop()随着DOM输出的变化而变化
    prop()作为复选框的originBoolean值的完整链接
    (pre-1.6)

  • 我们只能使用prop访问DOM元素,然后它会提供 undefined





<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>prop demo</title>
  <style>
    p {
      margin: 20px 0 0;
    }
    b {
      color: blue;
    }
  </style>

</head>

<body>

  <input id="check1" type="checkbox" checked="checked">
  <label for="check1">Check me</label>
  <p></p>

  <script>
    $("input").change(function() {
      var $input = $(this);
      $("p").html(
        ".attr( \"checked\" ): <b>" + $input.attr("checked") + "</b><br>" +
        ".prop( \"checked\" ): <b>" + $input.prop("checked") + "</b><br>" +
        ".is( \":checked\" ): <b>" + $input.is(":checked")) + "</b>";
    }).change();
  </script>

</body>

</html>



.prop()



.prop( propertyName )
propertyName
Type: String
The name of the property to get.

  
  .prop()方法仅获取第一个元素的属性值
  在匹配的集合中。它为属性的值返回undefined
  尚未设置,或匹配的集合没有元素。要得到
  单独使用每个元素的值,使用循环结构
  作为jQuery的.each()或.map()方法。



<html>
<head>
  <meta charset="utf-8">
  <title>prop demo</title>
  <style>
  p {
    margin: 20px 0 0;
  }
  b {
    color: blue;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>

<script>
$( "input" ).change(function() {
  var $input = $( this );
  $( "p" ).html(
    ".attr( \"checked\" ): <b>" + $input.attr( "checked" ) + "</b><br>" +
    ".prop( \"checked\" ): <b>" + $input.prop( "checked" ) + "</b><br>" +
    ".is( \":checked\" ): <b>" + $input.is( ":checked" ) + "</b>" );
}).change();
</script>

</body>
</html>


.attr()结果



.attr( attributeName )
attributeName
Type: String
The name of the attribute to get.

  
  .attr()方法仅获取第一个元素的属性值
  在匹配的集合中。要单独获取每个元素的值,
  使用循环结构,如jQuery的.each()或.map()方法。

  
  使用jQuery的.attr()方法获取元素的值
  属性有两个主要好处:

  
  方便:它可以直接在jQuery对象上调用并链接
  其他jQuery方法。跨浏览器一致性:一些值
  浏览器甚至是不一致地报告属性
  跨单个浏览器的版本。 .attr()方法d减少这样的
  不一致。



<html>
<head>
  <meta charset="utf-8">
  <title>attr demo</title>
  <style>
  em {
    color: blue;
    font-weight: bold;
  }
  div {
    color: red;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<p>Once there was a <em title="huge, gigantic">large</em> dinosaur...</p>

The title of the emphasis is:<div></div>

<script>
var title = $( "em" ).attr( "title" );
$( "div" ).text( title );
</script>

</body>
</html>

其它参考13


jQuery 1.6引入了.prop()函数并分离了DOM属性和属性,它引发了很多关于.attr和.prop函数之间差异的问题。


见下面的例子:


例如:1)


<input id="demo" type="text" dbvalue="Kansagara" />

$("#demo").attr("dbvalue");   // returns Kansagara
$("#demo").prop("dbvalue");   // returns undefined


.prop()只返回HTML DOM属性的值,它没有返回自定义属性的值,而.attr()也返回如上所示的自定义属性值。


实施例:2)


<input id="demo" type="text" value="Kansagara" />


现在,我在文本框中将文本'Kansagara'更改为'Hitesh'。


$("#demo").attr("value");   // returns Kansagara
$("#demo").prop("value");   // returns Hitesh


现在你已经知道这意味着什么。只更改了元素的属性,因为它在DOM中是动态的。但元素的属性是HTML文本,无法更改。从广义上讲,属性总是表示当前状态,而属性(IE的旧版本除外)表示初始状态或者是html属性,因为它们是严格定义的。该属性不会告诉您当前状态。


一个复选框(jquery 1.6+)


<input id="check1" checked="checked" type="checkbox" />

.attr('checked') //returns  checked
.prop('checked') //returns  true
.is(':checked') //returns true


prop方法返回checked,selected,disabled,readOnly..etc的布尔值,而attr返回已定义的字符串。因此,您可以在if条件下直接使用.prop('checked')。


.attr()在内部调用.prop(),因此.attr()方法比直接通过.prop()访问它们要慢一些。


对于jQuery 1.6+,将主要使用prop,因为它比attr简单且宽泛。在大多数旧项目中,attr用于获取元素的当前状态信息。但是现在道具已经完成了这项工作,并且attr将被替换为道具。


希望能帮助到你。

其它参考14


如果代码以这种方式编写,Gary Hole的答案与解决问题非常相关


obj.prop("style","border:1px red solid;")


由于prop函数返回CSSStyleDeclaration对象,上面的代码在某些浏览器中无法正常工作(在我的情况下用IE8 with Chrome Frame Plugin测试)。


从而将其更改为以下代码


obj.prop("style").cssText = "border:1px red solid;"


解决了这个问题。