所以 jQuery 1.6 有新功能 prop()
。
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
或者在这种情况下,他们做同样的事情?
如果我 做 必须切换到使用 prop()
,所有的旧 attr()
如果我切换到1.6,呼叫会中断吗?
UPDATE
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()
。
原始答案
如果您只使用过jQuery而不是直接使用DOM,那么这可能是一个令人困惑的变化,尽管它在概念上肯定是一种改进。对于使用jQuery的网站来说,这不太好,但是由于这种变化会破坏。
我将总结一下主要问题:
- 你通常想要
prop()
而不是attr()
。 - 在大多数情况下,
prop()
做什么attr()
以前做。更换呼叫attr()
同prop()
在你的代码中通常会工作。 - 属性通常比属性更容易处理。属性值可以只是一个字符串,而属性可以是任何类型。例如,
checked
property是一个布尔值style
property是一个对象,每个样式都有各自的属性size
财产是一个数字。 - 如果属性和具有相同名称的属性都存在,通常更新一个将更新另一个,但输入的某些属性不是这种情况,例如
value
和checked
:对于这些属性,属性始终表示当前状态,而属性(旧版IE中除外)对应于输入的默认值/ checkedness(反映在defaultValue
/defaultChecked
属性)。 - 这个更改删除了一些在属性和属性前面停留的魔法jQuery层,这意味着jQuery开发人员必须学习一些关于属性和属性之间的区别。这是件好事。
如果你是一个jQuery开发人员并且对整个业务的属性和属性感到困惑,那么你需要退后一步并学习一点,因为jQuery不再那么努力地保护你不受这些东西的影响。对于关于这个主题的权威但有点干的词,有规格: DOM4, HTML DOM, DOM级别2, DOM级别3。 Mozilla的DOM文档适用于大多数现代浏览器,并且比规范更易于阅读,因此您可以找到它们 DOM参考 很有帮助。有一个 关于元素属性的部分。
作为属性如何比属性更易于处理的示例,请考虑最初检查的复选框。以下是两个可能的有效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/。
我认为 蒂姆说得很好,但让我们退后一步:
DOM元素是一个对象,一个在内存中的东西。像OOP中的大多数对象一样 性能。它还单独包含元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。一些元素 性能 得到他们的 初始 价值来自 属性 具有相同或相似的名称(value
从“value”属性获取其初始值; href
从“href”属性获取其初始值,但它不是完全相同的值; className
来自“类”属性)。其他属性以其他方式获取其初始值:例如, parentNode
property根据其父元素获取其值;一个元素总是有一个 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”| |名称:“fooAnchor”| | id:“fooAnchor”| | className:“test one”| |属性:| | href:“foo.html”| |名称:“fooAnchor”| | id:“fooAnchor”| | class:“测试一个”| + ------------------------------------------- +
请注意,属性和属性是不同的。
现在,尽管它们是截然不同的,因为所有这些都是从头开始设计的,而不是从头开始设计,如果你设置它们,许多属性会回写它们派生的属性。但并非所有人都这样做,正如你所看到的那样 href
上面,映射并不总是直接“传递价值”,有时会涉及到解释。
当我谈到属性是对象的属性时,我不是在抽象地说。这是一些非jQuery代码:
var link = document.getElementById('fooAnchor');
alert(link.href); // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"
(这些值与大多数浏览器一样;有一些变化。)
该 link
对象是一个真实的东西,你可以看到访问一个真正的区别 属性 在它上面,访问一个 属性。
正如蒂姆所说, 绝大多数 当时,我们希望与物业合作。部分原因是因为它们的值(甚至是它们的名称)在浏览器中往往更加一致。我们大多只希望在没有与之相关的属性(自定义属性)时使用属性,或者当我们知道对于该特定属性时,属性和属性不是1:1(与 href
和上面的“href”)。
标准属性在各种DOM规范中列出:
这些规格有很好的索引,我建议保持链接方便;我一直都在使用它们。
自定义属性包括,例如,任何 data-xyz
您可能在元素上添加元数据以向代码提供元数据的属性(现在,只要您坚持使用HTML5,这就是HTML5的有效属性) data-
字首)。 (jQuery的最新版本允许您访问 data-xyz
元素通过 data
功能,但功能是 不 只是一个访问者 data-xyz
属性[它做得越来越少];除非你真的需要它的功能,否则我会使用它 attr
与...互动的功能 data-xyz
属性。)
该 attr
函数曾经有一些复杂的逻辑来获得他们想要的东西,而不是字面上得到属性。它混淆了这些概念。搬到 prop
和 attr
是为了解除他们的混乱。简而言之,在v1.6.0中jQuery在这方面走得太远了,但是功能性 很快被加回来了 至 attr
处理人们使用的常见情况 attr
从技术上讲他们应该使用 prop
。
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 Mode(及以下)需要get / set / removeAttribute中DOM属性的名称而不是属性名称。这是了解差异的重要原因之一。
DOM属性
句法:
document.body.onload = foo;
目的: 提供对属于元素节点的属性的访问。这些属性与属性类似,但只能通过JavaScript访问。这是一个重要的区别,有助于阐明DOM属性的作用。 请注意,属性与属性完全不同,因为此事件处理程序分配是无用的并且不会接收事件(正文没有onload事件,只有onload属性)。
可视化:
在这里,您将注意到Firebug中“DOM”选项卡下的属性列表。这些是DOM属性。你会立即注意到它们中的一些,因为你以前在不知情的情况下使用过它们。他们的价值观是你通过JavaScript获得的。
文档
例
HTML: <textarea id="test" value="foo"></textarea>
JavaScript的: alert($('#test').attr('value'));
在早期版本的jQuery中,这将返回一个空字符串。在1.6中,它返回适当的值, foo
。
在没有浏览任何一个函数的新代码的情况下,我可以充满信心地说,混淆更多地与HTML属性和DOM属性之间的差异有关,而不是与代码本身有关。希望这能为你解决一些问题。
-Matt
属性在DOM中; HTML中的属性被解析为DOM。
更多细节
如果更改属性,则更改将反映在DOM中(有时使用不同的名称)。
示例:更改 class
标签的属性将改变 className
DOM中该标记的属性。
如果标记上没有属性,则仍具有相应的DOM属性,其属性为空或默认值。
示例:虽然您的标签没有 class
属性,DOM属性 className
确实存在空字符串值。
编辑
如果更改一个,另一个将由控制器更改,反之亦然。 这个控制器不在jQuery中,而是在浏览器的本机代码中。
只是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('blah')
:返回'apple'
是吗?为什么不在这个元素上设置“梨”。因为属性是在输入属性上更改的,而不是DOM输入元素本身 - 它们基本上几乎彼此独立工作。$('input').prop('blah')
:返回'pear'
你真正需要小心的事情就是 在整个应用程序中,不要将这些用法混合使用相同的属性 由于上述原因。
看一下展示差异的小提琴: http://jsfiddle.net/garreh/uLQXc/
.attr
VS .prop
:
第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')
TL; DR
使用 prop()
过度 attr()
在大多数情况下。
一个 属性 是输入元素的当前状态。一个 属性 是默认值。
属性可以包含不同类型的东西。属性只能包含字符串
肮脏的检查
这个概念是一个可以观察到差异的例子: 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>
对于某些属性,如 disabled
上 button
,添加或删除内容属性 disabled="disabled"
总是切换属性(在HTML5中称为IDL属性),因为 http://www.w3.org/TR/html5/forms.html#attr-fe-disabled 说:
禁用的IDL属性必须反映已禁用的内容属性。
所以你可能会侥幸逃脱它,虽然它很难看,因为它不需要修改HTML。
对于其他属性,如 checked="checked"
上 input type="checkbox"
事情破裂,因为一旦你点击它,它就会变脏,然后添加或删除 checked="checked"
内容属性 不再切换检查。
这就是你应该主要使用的原因 .prop
,因为它直接影响有效性质,而不是依赖复杂的副作用。
一切都在文档中:
在特定情况下,属性和属性之间的差异可能很重要。在jQuery 1.6之前,.attr()方法有时在检索某些属性时会考虑属性值,这可能会导致行为不一致。从jQuery 1.6开始,.prop()方法提供了一种显式检索属性值的方法,而.attr()只检索属性。
所以使用道具!
属性 在你的HTML中 文本文件/文件 (==想象这是你的html标记解析的结果),而
性能是HTML格式 DOM树 (==基本上是JS意义上某个对象的实际属性)。
重要的是,其中许多是同步的(如果你更新 class
属性, class
html中的属性也会更新;否则)。 但 某些属性可能会同步到意外的属性 - 例如, 属性 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()
据说比它快约2.5倍.attr()
。
.attr()
:
- 获得一个的价值 属性 对于匹配元素集中的第一个元素。
- 为您提供元素的值,因为它是在页面加载的html中定义的
.prop()
:
- 获得a的价值 属性 对于匹配元素集中的第一个元素。
- 提供通过javascript / jquery修改的元素的更新值