$(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>
(另请参见此提琴: http : //jsfiddle.net/maniator/JpUF2/ )
控制台将getAttribute
作为字符串记录,将attr
作为字符串记录,但将prop
作为CSSStyleDeclaration
,为什么? 将来如何影响我的编码?
#1楼
通常,您需要使用属性。 仅将属性用于:
- 获取自定义HTML属性(因为它未与DOM属性同步)。
- 获取与DOM属性不同步的HTML属性,例如,获取标准HTML属性的“原始值”,例如
<input value="abc">.
#2楼
脏检查
这个概念提供了一个可以观察到差异的示例: http : //www.w3.org/TR/html5/forms.html#concept-input-checked-dirty
试试看:
- 单击按钮。 两个复选框都被选中。
- 取消选中两个复选框。
- 再次单击该按钮。 只有
prop
复选框被选中。 砰!
$('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>
对于某些属性(如button
disabled
,添加或删除内容属性disabled="disabled"
总是会切换属性(在HTML5中称为IDL属性),因为http://www.w3.org/TR/html5/forms.html#attr -fe-disabled说:
禁用的IDL属性必须反映禁用的内容属性。
因此尽管它很丑陋,因为它不需要修改HTML,但您可能会摆脱它。
对于其他属性,例如input type="checkbox"
checked="checked"
上的checked="checked"
,事情就中断了,因为一旦单击它,它就会变脏,然后添加或删除checked="checked"
内容属性将不再切换checkness 。
这就是为什么您应该主要使用.prop
,因为它直接影响有效属性,而不是依赖于修改HTML的复杂副作用。
#3楼
TL; DR
在大多数情况下,在attr()
使用prop()
。
属性是输入元素的当前状态。 属性是默认值。
一个属性可以包含不同类型的事物。 属性只能包含字符串
#4楼
attributes
-> HTML
properties
-> DOM
#5楼
属性位于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/ )
下表显示了首选.prop()
位置(即使仍然可以使用.attr()
)。
在正式建议使用后者的情况下,为什么有时要使用.prop()而不是.attr()?
-
.prop()
可以返回任何类型-字符串,整数,布尔值;.attr()
始终返回一个字符串。 -
.prop()
比.attr()
快约2.5倍。
#6楼
如果代码是以这种方式编写的,那么Gary Hole答案与解决问题非常相关
obj.prop("style","border:1px red solid;")
由于prop函数返回CSSStyleDeclaration
对象,因此以上代码在某些浏览器中将无法正常工作(在我的情况下已通过IE8 with Chrome Frame Plugin
进行了测试)。
因此将其更改为以下代码
obj.prop("style").cssText = "border:1px red solid;"
解决了问题。
#7楼
轻轻提醒您使用prop()
,例如:
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函数用于检查是否选中了checkbox1,如果选中,则返回1;否则,返回0。 如果不是,则返回0。函数prop()在此处用作GET函数。
if ($("#checkbox1").prop('checked', true)) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函数用于将checkbox1设置为选中状态,并始终返回1。现在将函数prop()用作SET函数。
别搞砸了
P / S:当我检查Image src属性时。 如果src为空,则prop返回页面的当前URL(错误),而attr返回空字符串(右)。
#8楼
在jQuery 1.6之前, attr()
方法在检索属性时有时会考虑属性值,这会导致行为的不一致。
prop()
方法的引入提供了一种显式检索属性值的方法,而.attr()
检索属性。
文件:
jQuery.attr()
获取匹配元素集中第一个元素的属性值。
jQuery.prop()
获取匹配元素集中第一个元素的属性值。
#9楼
.attr()
:
- 获取匹配元素集中第一个元素的属性值。
- 提供页面加载时html中定义的element的值
.prop()
:
- 获取匹配元素集中第一个元素的属性值。
- 给出通过javascript / jquery修改的元素的更新值
#10楼
1)属性在DOM中; HTML中的一个属性被解析为DOM。
2)$(elem).attr(“ checked”)(1.6.1+)“ checked”(String)将随着复选框状态更改
3)$(elem).attr(“ checked”)(1.6之前)true(布尔值)更改为复选框状态
通常,我们想用于DOM对象,而不是自定义属性,例如
data-img, data-xyz
。在访问
checkbox
值和带有attr()
和prop()
href
时的一些区别也有所不同,因为DOM输出带有prop()
作为从origin
到复选框的Boolean
值的完整链接的DOM输出(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>
#11楼
.attr()
可以做到的一件事.prop()
不能做到:影响CSS选择器
这是我在其他答案中没有看到的一个问题。
CSS选择器[name=value]
- 将响应
.attr('name', 'value')
- 但不总是
.prop('name', 'value')
.prop()
仅影响几个属性选择器
-
input[name]
(感谢@TimDown )
.attr()
影响所有属性选择器
-
input[value]
-
input[naame]
-
span[name]
-
input[data-custom-attribute]
(。input[data-custom-attribute]
.data('custom-attribute')
都不会影响此选择器)
#12楼
全部都在文档中 :
属性和属性之间的差异在特定情况下可能很重要。 在jQuery 1.6之前,.attr()方法在检索某些属性时有时会考虑属性值,这可能会导致行为不一致。 从jQuery 1.6开始,.prop()方法提供了一种显式检索属性值的方法,而.attr()则检索属性。
所以使用道具!
#13楼
对于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");
属性以字符串形式返回,并且在浏览器之间可能不一致。 但是,它们在某些情况下可能至关重要。 如上所示,IE 8 Quirks模式(及以下版本)期望get / set / removeAttribute中的DOM属性名称而不是属性名称。 这是了解差异很重要的众多原因之一。
DOM属性
句法:
document.body.onload = foo;
目的:允许访问属于元素节点的属性。 这些属性类似于属性,但是只能通过JavaScript访问。 这是一个重要的区别,有助于阐明DOM属性的作用。 请注意,属性与properties完全不同 ,因为此事件处理程序分配是无用的,并且不会接收该事件(主体没有onload事件,只有onload属性)。
可视化:
在这里,您会注意到Firebug中“ DOM”选项卡下的属性列表。 这些是DOM属性。 您会立即注意到其中的很多,因为您在不知不觉中就已经使用过它们。 它们的值就是您将通过JavaScript收到的值。
文献资料
例
HTML: <textarea id="test" value="foo"></textarea>
JavaScript: alert($('#test').attr('value'));
在早期版本的jQuery中,这将返回一个空字符串。 在1.6中,它返回适当的值foo
。
不用看这两个函数的新代码,我可以自信地说,混淆更多是与HTML属性和DOM属性之间的差异有关,而不是与代码本身有关。 希望这可以为您解决一些问题。
-马特
#14楼
2012年11月1日更新
我的原始答案专门适用于jQuery 1.6。 我的建议保持不变,但jQuery 1.6.1进行了一些细微更改:面对预期的一堆破损网站,jQuery团队将attr()
恢复为接近(但不完全相同)的布尔属性旧行为。 。 约翰·雷西格(John Resig)也对此发表了博客 。 我可以看到他们遇到的困难,但仍然不同意他对attr()
推荐。
原始答案
如果您只使用过jQuery,而没有直接使用过DOM,则这可能是一个令人困惑的更改,尽管从概念上来说这绝对是一种改进。 对于使用jQuery的成千上万的网站来说,效果不是很好,但是由于此更改,这些网站将中断。
我将总结主要问题:
- 您通常需要
prop()
而不是attr()
。 - 在大多数情况下,
prop()
执行attr()
过去的工作。 通常,可以在代码中用prop()
替换对attr()
调用。 - 属性通常比属性更容易处理。 属性值只能是字符串,而属性可以是任何类型。 例如,
checked
属性是一个布尔值,style
属性是一个对象,每个对象都有各自的属性,size
属性是一个数字。 - 当一个属性和一个具有相同名称的属性同时存在时,通常更新一个属性会更新另一个属性,但是对于某些输入属性(例如
value
和checked
则不是这种情况:对于这些属性,该属性始终表示当前状态而属性(旧版IE中除外)对应于输入的默认值/检查(反映在defaultValue
/defaultChecked
属性中)。 - 这项更改消除了固定在属性和属性前面的jQuery魔术层,这意味着jQuery开发人员将不得不学习一些有关属性和属性之间差异的知识。 这是一件好事。
如果您是jQuery开发人员,并且对整个业务都对属性和属性感到困惑,那么您需要退后一步,并对其有所了解,因为jQuery不再那么努力地使您远离这些东西。 对于有关该主题的权威性但有些措手不及的单词,有以下规范: DOM4 , HTML DOM , DOM Level 2 , DOM Level 3 。 Mozilla的DOM文档对大多数现代浏览器均有效,并且比规范更易于阅读,因此您可能会发现其DOM参考有用。 关于元素属性的一节 。
作为如何比属性更容易处理属性的示例,请考虑一个最初选中的复选框。 这是有效的HTML可能有两个片段:
<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">
那么,如何确定jQuery是否选中了该复选框? 查看堆栈溢出,通常会发现以下建议:
-
if ( $("#cb").attr("checked") === true ) {...}
-
if ( $("#cb").attr("checked") == "checked" ) {...}
-
if ( $("#cb").is(":checked") ) {...}
实际上,这是世界上最简单的事情:使用checked
Boolean属性,自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/ 。
#15楼
我认为蒂姆说得很好 ,但让我们退后一步:
DOM元素是对象,是内存中的东西。 像OOP中的大多数对象一样,它具有properties 。 它还分别具有在元素上定义的属性的映射(通常来自浏览器为创建元素而读取的标记)。 有些元素的属性从具有相同或相似名称的属性 (获取其初始值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规范中列出了标准属性:
这些规范具有出色的索引,我建议您随时保持指向它们的链接; 我一直都在用它们。
自定义属性包括,例如,您可能会在元素上放置的任何data-xyz
属性,以向代码提供元数据(现在,从HTML5开始,只要您坚持使用data-
prefix, data-
)。 (jQuery的最新版本使您可以通过data
函数访问data-xyz
元素,但是该函数不仅是data-xyz
属性的访问器[它做的更多和更少];除非您确实需要它的功能,否则我将使用attr
函数与data-xyz
属性进行交互。)
attr
函数过去在获取他们认为想要的东西时有一些复杂的逻辑,而不是从字面上获取属性。 它混淆了这些概念。 转向prop
和attr
是要取消它们的合并。 简而言之,在v1.6.0中jQuery在这方面走得太远了,但是功能很快就被添加回 attr
以处理人们在技术上应该使用prop
时使用attr
的常见情况。
#16楼
只是HTML属性和DOM对象之间的区别引起了混乱。 对于那些this.src
使用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('blah')
:返回'apple'
吗? 为什么不将“梨”设置为该元素的最后一个。 因为属性是在输入属性上更改的,而不是DOM输入元素本身的更改-它们基本上几乎彼此独立地工作。 -
$('input').prop('blah')
:返回'pear'
出于上述原因,您真正需要注意的事情就是不要在整个应用程序中为同一属性混合使用这些方法 。
看到证明不同的小提琴: http : //jsfiddle.net/garreh/uLQXc/
.attr
与.prop
:
第一轮:风格
<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')
#17楼
属性在DOM中; HTML中的一个属性被解析为DOM。
更多细节
如果更改属性,则更改将反映在DOM中(有时使用不同的名称)。
示例:更改标签的class
属性将更改DOM中该标签的className
属性。 如果标签上没有属性,则仍然具有带有空值或默认值的相应DOM属性。
示例:尽管您的标签没有class
属性,但是DOM属性className
确实存在,并且具有空字符串值。
编辑
如果更改一个,则另一个将由控制器更改,反之亦然。 该控制器不在jQuery中,而是在浏览器的本机代码中。