所以jQuery1.6有了新的函数prop()。

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

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

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

更新

选择器='#id'$(选择器).click(函数){//而不是:var getAtt=this.getAttribute('style');//我是否使用:var thisProp=$(this).prop('style');//或:var thisAttr=$(this).attr(“样式”);console.log(getAtt、thisProp、thisAttr);});<script src=“https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js“></script>测试</div>

(另请参见此小提琴:http://jsfiddle.net/maniator/JpUF2/)

控制台将getAttribute作为字符串记录,将attr作为字符串记录但将prop作为CSSStyleDeclaration记录,为什么?这对我未来的编码有何影响?


所有内容都在文档中:

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

所以使用道具!


对于jQuery来说,这一变化已经发生了很长时间。多年来,他们一直满足于一个名为attr()的函数,该函数主要检索DOM财产,而不是您期望从名称中得到的结果。attr()和prop()的分离应该有助于缓解HTML属性和DOM财产.$之间的一些混淆。fn.prop()获取指定的DOM属性,而$.fn.attr()获取特定的HTML属性。

为了充分理解它们的工作原理,这里有一个关于HTML属性和DOM财产之间差异的扩展解释

HTML属性

语法:

<body onload=“foo()”>

目的:允许标记将数据与之关联,以用于事件、渲染和其他目的。

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

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

属性以字符串形式返回,并且在浏览器之间可能不一致。然而,它们在某些情况下可能至关重要。如上所述,IE8QuirksMode(及以下)期望get/set/removeAttribute中的DOM属性名称,而不是属性名称。这是了解差异很重要的众多原因之一。

DOM财产

语法:

document.body.onload=foo;

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

可视化:

在这里,您会注意到Firebug中“DOM”选项卡下的财产列表。这些是DOM财产。你会立即注意到其中的很多,因为你以前会在不知道的情况下使用它们。它们的值就是你通过JavaScript收到的值。

文档

JavaScript:最终指南大卫·福莱纳根HTML属性,Mozilla开发中心Mozilla开发中心DOM元素财产

实例

HTML:<textarea id=“test”value=“foo”></textarea>

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

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

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

-马特


2012年11月1日更新

我最初的答案特别适用于jQuery1.6。我的建议保持不变,但jQuery 1.6.1稍微改变了一些事情:面对预测的一堆破碎的网站,jQuery团队将attr()恢复到了接近(但不完全相同)其布尔属性的旧行为。John Resig也在博客中谈到了这一点。我可以看到他们遇到的困难,但仍然不同意他的建议,更喜欢attr()。

原答覆

如果您只使用过jQuery,而没有直接使用过DOM,那么这可能是一个令人困惑的变化,尽管这在概念上肯定是一个改进。不过,对于使用jQuery的大量网站来说,这并不太好,因为这一变化会导致网站崩溃。

我将总结主要问题:

通常需要prop()而不是attr()。在大多数情况下,prop()执行attr()以前的操作。在代码中用prop(()替换对attr(的调用通常是有效的。财产通常比属性更容易处理。属性值只能是字符串,而属性可以是任何类型。例如,选中的属性是布尔值,样式属性是每个样式都有单独财产的对象,大小属性是数字。如果同时存在具有相同名称的属性和属性,通常更新一个属性会更新另一个属性,但输入的某些属性(例如value和checked)并非如此:对于这些属性,属性始终表示当前状态,而属性(旧版本的IE除外)对应于输入的默认值/检查(反映在defaultValue/defaultChecked属性中)。这一更改删除了一些停留在属性和财产前面的神奇jQuery层,这意味着jQuery开发人员必须了解财产和属性之间的区别。这是一件好事。

如果您是一名jQuery开发人员,对财产和属性的整个业务感到困惑,那么您需要后退一步,稍微了解一下,因为jQuery不再试图保护您不受这些东西的影响。关于这个主题的权威但有些枯燥的词汇,有一些规范:DOM4、HTMLDOM、DOMLevel 2、DOMLevel 3。Mozilla的DOM文档适用于大多数现代浏览器,并且比规范更容易阅读,因此您可能会发现它们的DOM参考很有用。有一节是关于元素财产的。

作为财产比属性更容易处理的示例,请考虑一个最初选中的复选框。这里有两种可能的有效HTML:

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

那么,如何确定jQuery是否选中了复选框?查看堆栈溢出,您通常会发现以下建议:

如果($(“#cb”).attr(“checked”)==true){…}如果($(“#cb”).attr(“check”)==“checked”){…}如果($(“#cb”).is(“:checked”)){…}

这实际上是世界上使用选中的布尔属性最简单的事情,自1995年以来,它在每个主要的可脚本化浏览器中都存在并完美运行:

if(document.getElementById(“cb”).checked){…}

该属性还使选中或取消选中复选框变得微不足道:

document.getElementById(“cb”).checked=false

在jQuery1.6中,这明确地变成

$(“#cb”).prop(“checked”,false)

使用checked属性编写复选框脚本的想法是无益的,也是不必要的。这是你需要的。

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


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

DOM元素是一个对象,一个内存中的东西。与OOP中的大多数对象一样,它具有财产。另外,它还有一个在元素上定义的属性映射(通常来自浏览器为创建元素而读取的标记)。一些元素的财产从具有相同或相似名称的属性中获取初始值(value从“value”属性中获取其初始值;href从“href”属性中获得其初始值,但它不是完全相同的value;className从“class”属性中)。其他财产以其他方式获取其初始值:例如,parentNode属性根据其父元素的内容获取其值;元素始终具有style属性,无论它是否具有“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"

(这些值与大多数浏览器相同;存在一些差异。)

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

正如蒂姆所说,大多数时候,我们都想与财产合作。这部分是因为它们的值(甚至它们的名称)在浏览器之间趋于一致。我们通常只希望在没有与属性相关的属性(自定义属性)时使用属性,或者当我们知道特定属性的属性和属性不是1:1时(如上面的href和“href”)。

各种DOM规范中列出了标准财产:

DOM2 HTML(大部分已过时,请参见HTML规范)DOM2核心(过时)DOM3核心(过时)域4

这些规范有很好的索引,我建议将链接放在手边;我一直在用。

例如,自定义属性将包括任何数据xyz属性,您可以将这些属性放在元素上,以向代码提供元数据(现在,这在HTML5中是有效的,只要您坚持数据前缀)。(jQuery的最新版本允许您通过数据函数访问数据xyz元素,但该函数不仅仅是数据xyz属性的访问器[它做的更多也更少];除非您实际需要它的功能,否则我会使用attr函数与数据xyz特性交互。)

attr函数过去有一些复杂的逻辑来获得他们认为你想要的东西,而不是从字面上获得属性。它将这些概念混为一谈。移动到prop和attr是为了将它们分开。简而言之,在v1.6.0中,jQuery在这方面做得太过火了,但功能很快被添加回attr,以处理人们在技术上应该使用prop时使用attr的常见情况。


只是HTML属性和DOM对象之间的区别导致了混淆。对于那些习惯于使用DOM元素的本地财产(比如this.src this.value this.checked等)的人来说,.prop是对这个家庭的热烈欢迎。对其他人来说,这只是增加了一层混乱。让我们澄清一下。

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

<input blah="hello">

$('input').attr('blah'):按预期返回'hello'。这里没有惊喜。$('input').prop('blah'):返回undefined——因为它正在尝试执行[HTMLInputElement].blah——并且该DOM对象上不存在这样的属性。它仅作为该元素的属性存在于作用域中,即[HTMLInputElement].getAttribute('blah')

现在我们改变了一些事情,比如:

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

$('input').attr('beah'):返回'apple'是吗?为什么不“梨”,因为这是最后一个元素。因为属性是在输入属性上更改的,而不是DOM输入元素本身——它们基本上彼此独立工作。$('input').prop('beah'):返回'pear'

您真正需要注意的是,不要因为上述原因而在整个应用程序中混合使用相同的属性。

看到一把小提琴展示了不同之处:http://jsfiddle.net/garreh/uLQXc/


属性与属性:

第1轮:风格

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

.attr('style')--返回匹配元素的内联样式,即“font:arial;”.prop('style')--返回一个样式声明对象,即CSSStyleDeclaration

第二轮:价值

<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')


DOM中有一个属性;属性在HTML中,该HTML被解析为DOM。

进一步的细节

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

示例:更改标记的class属性将更改DOM中该标记的className属性(这是因为类已被使用)。如果标记上没有属性,那么相应的DOM属性仍然为空或默认值。

示例:虽然标记没有class属性,但DOM属性className确实存在空字符串值。

edit

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


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

获取自定义HTML属性(因为它未与DOM属性同步)。获取与DOM属性不同步的HTML属性,例如获取标准HTML属性的“原始值”,如<input value=“abc”>。


肮脏的检查

该概念提供了一个可观察到差异的示例:http://www.w3.org/TR/html5/forms.html#concept-输入检查过脏

试试看:

单击按钮。两个复选框都被选中。取消选中这两个复选框。再次单击按钮。只有道具复选框被选中。砰!

$('按钮').on('单击',函数(){$('#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”>设置选中的属性和属性</按钮>

对于某些属性,如按钮上的disabled,添加或删除content属性disabled=“disabled”总是切换属性(在HTML5中称为IDL属性),因为http://www.w3.org/TR/html5/forms.html#attr-fe残疾人说:

禁用的IDL属性必须反映禁用的内容属性。

所以你可以摆脱它,尽管它很难看,因为它不需要修改HTML。

对于其他属性,如inputtype=“checkbox”上的checked=“checked”,事情就会中断,因为一旦单击它,它就会变脏,然后添加或删除checked=”checked“内容属性将不再切换checked。

这就是为什么应该主要使用.prop,因为它直接影响有效属性,而不是依赖于修改HTML的复杂副作用。


TL;博士

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

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

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


属性->HTML

财产->DOM


属性在HTML文本文档/文件中(==想象这是解析HTML标记的结果),而财产位于HTMLDOM树中(==基本上是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/)

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


为什么您有时会想使用.prop()而不是.attr(),后者是官方推荐的?

.prop()可以返回任何类型-string、integer、boolean;而.attr()始终返回字符串。.prop()据说比.attr()快2.5倍。


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

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

由于prop函数返回CSSStyleDeclaration对象,上述代码在某些浏览器中无法正常工作(在我的例子中,使用带有Chrome框架插件的IE8进行了测试)。

因此,将其更改为以下代码

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

解决了问题。


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

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

上面的函数用于检查checkbox 1是否选中,如果选中:返回1;如果没有:返回0。函数prop()在这里用作GET函数。

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

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

别搞砸了。

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


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

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

文件:

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

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


.attr():

获取匹配元素集合中第一个元素的属性值。为您提供页面加载时html中定义的元素值

.prop():

获取匹配元素集合中第一个元素的属性值。提供通过javascript/jquery修改的元素的更新值


1) DOM中有一个属性;HTML中有一个属性解析为DOM。2) $(elem).attr(“检查”)(1.6.1+)“检查”(字符串)将更改复选框状态3) $(elem).attr(“已检查”)(1.6之前)true(布尔值)已更改带有复选框状态

大多数情况下,我们希望使用DOM对象,而不是自定义属性如数据img、数据xyz。访问复选框值和href时也有一些不同属性()和属性()随DOM输出的变化而变化prop()作为来自原点的完整链接和复选框的布尔值(1.6之前)我们只能使用propother访问DOM元素,否则它将不定义

<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>道具演示</title><style>p型{边距:20px 0 0;}b级{颜色:蓝色;}</style></head><body><input id=“check1”type=“checkbox”checked=“checked”><label for=“check1”>检查我</label><p></p><脚本>$(“input”).change(函数){var$input=$(this);$(“p”).html(“.attr(\”已检查\“):<b>”+$input.attr“(”已检查“)+”</b><br>“+“.prop(\”checked\“):<b>”+$input.prop(”checked“)+“</b><br>”+“.is(\”:已检查\“):<b>”+$input.is(“:已检查”))+“</b>”;}).change();</script></body></html>


有一件事.attr()可以做到。prop()不能做到:影响CSS选择器

这是我在其他答案中没有看到的问题。

CSS选择器[名称=值]

将响应.attr('name','value')但不总是.prop('name','value')

.prop()仅影响少数属性选择器

输入[name](谢谢@TimDown)

.attr()影响所有属性选择器

输入[值]输入[名称]span[名称]input[data自定义属性](.data('custom-attribute')都不会影响此选择器)


在prop()与attr()中,几乎没有其他注意事项:

selectedIndex、tagName、nodeName、nodeType、ownerDocument、defaultChecked和defaultSelected。。应使用.prop()方法检索和设置。这些属性没有相应的属性,只是财产。输入类型复选框.attr('checked')//返回已检查.prop('checked')//返回true.is(“:checked”)//返回trueprop方法返回选中、选中、禁用或禁用的布尔值,只读。。而attr返回定义的字符串。所以,你可以直接在if条件下使用.prop('checked')。.attr()在内部调用.prop(),因此.attr比直接通过.prop()访问它们慢。