.prop() 与 .attr()
- 2024-11-02 21:00:00
- admin 原创
- 57
问题描述:
所以jQuery 1.6有了这个新功能prop()
。
$(selector).click(function(){
//instead of:
this.getAttribute('style');
//do i use:
$(this).prop('style');
//or:
$(this).attr('style');
})
或者在这种情况下他们做同样的事情吗?
如果我确实必须切换到使用,那么如果我切换到 1.6,prop()
所有旧的调用都会中断吗?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>
运行代码片段Hide results展开片段
(另请参阅此小提琴: http: //jsfiddle.net/maniator/JpUF2/)
控制台将 打印getAttribute
为字符串,将 打印attr
为字符串,但将 打印prop
为CSSStyleDeclaration
,为什么?这会对我以后的编码产生什么影响?
解决方案 1:
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
是布尔值,style
属性是具有每种样式的单独属性的对象,size
属性是数字。当属性 (property) 和特性 (attribute) 同时存在时,通常更新其中一个也会更新另一个,但对于输入的某些特性 (例如
value
和 )并非如此checked
:对于这些特性 (property),属性 (property) 始终代表当前状态,而特性 (attribute)(旧版本的 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 确定复选框是否被选中?查看 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/。
解决方案 2:
我认为蒂姆说得很好,但让我们回顾一下:
DOM 元素是一个对象,是内存中的一个东西。与 OOP 中的大多数对象一样,它具有属性。它还单独具有元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记)。元素的某些属性从具有相同或相似名称的属性获取其初始值(从“value”属性获取其初始值;从“href”属性获取其初始值,但不完全相同;从“class”属性获取)。其他属性以其他方式获取其初始值:例如,属性根据其父元素获取其值;元素始终具有属性,无论它是否具有“style”属性。value
`hrefclassName
parentNode`style
让我们考虑页面中的这个锚点http://example.com/testing.html
:
<a href="foo.html" class="test one" name="fooAnchor" id="fooAnchor">Hi</a>
一些免费的 ASCII 艺术(省略了很多东西):
+--------------------------------------+
| HTML锚元素 |
+--------------------------------------+
| href: “http://example.com/foo.html” |
| 名称:“fooAnchor”|
| 标识号:“fooAnchor”|
| className: "测试一" |
| 属性:+−−−−−−−−−−−−−−−−−−−−−−−−−−−+ |
| | href:“foo.html”||
|| 名称:“fooAnchor”||
|| 标识:“fooAnchor”||
| | 类:“测试一”||
| +------------+ | +------------+ |
+--------------------------------------+
请注意,属性 (property) 和特性 (attribute) 是不同的。
现在,尽管它们是不同的,但由于所有这些都是逐渐发展起来的,而不是从头开始设计的,因此如果您设置它们,许多属性都会写回到它们派生的属性。但并非所有属性都是这样,正如您从href
上面看到的,映射并不总是直接“传递值”,有时还涉及解释。
当我说属性是对象的属性时,我并不是抽象地说。以下是一些非 jQuery 代码:
const link = document.getElementById("fooAnchor");
console.log(link.href); // Shows "http://example.com/foo.html"
console.log(link.getAttribute("href")); // Shows "foo.html"
对象是真实存在的,并且您可以看到,访问其属性 (property)和访问特性 (attribute)link
之间存在着真正的区别。
正如 Tim 所说,绝大多数情况下,我们都希望使用属性。部分原因是它们的值(甚至名称)在各个浏览器之间往往更加一致。我们大多只希望在没有与之相关的属性(自定义属性)时使用属性,或者当我们知道对于该特定属性,属性和属性不是 1:1 时(如href
上面的“href”)。
标准属性在各种 DOM 规范中都有列出:
DOM2 HTML (已基本过时,请参阅HTML 规范)
DOM2 核心 (已过时)
DOM3 核心 (已过时)
DOM4
这些规格有出色的索引,我建议保留它们的链接;我一直在使用它们。
例如,自定义属性包括data-xyz
您可能放在元素上的任何属性,以便为您的代码提供元数据(现在,只要您坚持使用data-
前缀,这在 HTML5 中是有效的)。(jQuery 的最新版本允许您通过函数访问data-xyz
元素data
,但该函数不仅仅是属性的访问器data-xyz
[它既能做更多的事情,也能做更少的事情];除非您确实需要它的功能,否则我会使用该attr
函数与属性进行交互data-xyz
。)
该attr
函数过去有一些复杂的逻辑,用于获取他们认为您想要的内容,而不是直接获取属性。它混淆了概念。移至prop
和attr
旨在消除它们之间的混淆。在 v1.6.0 中,jQuery 在这方面做得有点过头了,但很快又将功能添加回了,以处理人们在技术上应该使用时attr
使用 的常见情况。attr
`prop`
解决方案 3:
对于 jQuery 来说,这一变化已经酝酿了很长时间。多年来,他们一直满足于一个名为的函数,该函数主要检索 DOM 属性,而不是您从名称中期望的结果。和attr()
的分离应该有助于缓解 HTML 属性和 DOM 属性之间的一些混淆。抓取指定的 DOM 属性,而抓取指定的 HTML 属性。attr()
`prop()$.fn.prop()
$.fn.attr()`
为了全面理解它们的工作原理,这里是对 HTML 属性和 DOM 属性之间区别的扩展解释:
HTML 属性
句法:
<body onload="foo()">
目的:
允许标记拥有与其关联的数据,用于事件、渲染和其他目的。
可视化:
此处主体上显示了类属性。可通过以下代码访问:
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 属性的作用。请注意,属性与属性完全不同,因为此事件处理程序分配毫无用处,不会接收事件(body 没有 onload 事件,只有 onload 属性)。
可视化:
在这里,您会注意到 Firebug 中“DOM”选项卡下有一个属性列表。这些是 DOM 属性。您会立即注意到其中的很多属性,因为您以前可能不知道就用过它们。它们的值就是您将通过 JavaScript 接收的值。
文档
JavaScript:David Flanagan 的权威指南
HTML 属性,Mozilla 开发中心
DOM 元素属性,Mozilla 开发中心
例子
HTML:<textarea id="test" value="foo"></textarea>
JavaScript的:alert($('#test').attr('value'));
在早期版本的 jQuery 中,这会返回一个空字符串。在 1.6 中,它会返回正确的值foo
。
无需查看这两个函数的新代码,我可以自信地说,混淆更多的是与 HTML 属性和 DOM 属性之间的差异有关,而不是与代码本身有关。希望这能为您澄清一些问题。
-马特
解决方案 4:
属性 (Property) 位于 DOM 中;属性 (Attribute) 位于解析到 DOM 中的 HTML 中。
更多细节
如果更改某个属性,则该更改将反映在 DOM 中(有时会使用不同的名称)。
示例:更改class
标签的属性将更改className
该标签在 DOM 中的属性(这是因为class
是 JavaScript 中的保留字,不能用作属性名)。如果标签上没有属性,则仍具有相应的 DOM 属性,其值为空或具有默认值。
示例:虽然您的标签没有class
属性,但 DOM 属性className
确实存在且具有空字符串值。
编辑
如果你改变其中一个,另一个也会被一个控制器改变,反之亦然。这个控制器不是在 jQuery 中,而是在浏览器的原生代码中。
解决方案 5:
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'
是 eh?为什么不是“pear”,因为这是在该元素上最后设置的。因为属性是在输入属性上更改的,而不是 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')
解决方案 6:
总结
大多数情况下使用prop()
over 。attr()
属性(property)是输入元素的当前状态。特性(attribute)是默认值。
属性可以包含不同类型的内容。属性只能包含字符串
解决方案 7:
肮脏的检查
这个概念提供了一个可观察到差异的例子: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>
运行代码片段Hide results展开片段
对于某些属性(例如disabled
on )button
,添加或删除内容属性disabled="disabled"
始终会切换属性(在 HTML5 中称为 IDL 属性),因为http://www.w3.org/TR/html5/forms.html#attr-fe-disabled说:
禁用的 IDL 属性必须反映禁用的内容属性。
因此你可能会摆脱它,尽管它很丑陋,因为它在不需要的情况下修改了 HTML。
对于其他属性(比如checked="checked"
on )input type="checkbox"
,事情就会变得混乱,因为一旦你点击它,它就会变脏,然后添加或删除checked="checked"
内容属性就不会再切换选中状态。
这就是为什么您应该使用 mainly 的原因.prop
,因为它直接影响有效属性,而不是依赖修改 HTML 的复杂副作用。
解决方案 8:
所有内容都在文档中:
属性和特性之间的区别在特定情况下可能很重要。在 jQuery 1.6 之前,.attr() 方法在检索某些属性时有时会考虑特性值,这可能会导致不一致的行为。从 jQuery 1.6 开始,.prop() 方法提供了一种显式检索特性值的方法,而 .attr() 则检索属性。
所以使用道具!
解决方案 9:
属性位于您的 HTML文本文档/文件中(== 想象这是您的 html 标记解析的结果),而
属性位于 HTML DOM 树中(== 基本上是 JS 意义上某个对象的实际属性)。
重要的是,它们中的许多都是同步的(如果你更新class
property ,class
html 中的 attribute 也会更新;否则)。但有些 attribute 可能会同步到意外的属性 - 例如,attribute checked
对应于property 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()
。
解决方案 10:
.attr()
:
获取匹配元素集合中第一个元素的属性值。
为您提供页面加载时在 html 中定义的元素值
.prop()
:
获取匹配元素集合中第一个元素的属性值。
提供通过 javascript/jquery 修改的元素的更新值
解决方案 11:
通常情况下,您需要使用属性。仅将属性用于:
获取自定义 HTML 属性(因为它未与 DOM 属性同步)。
获取与 DOM 属性不同步的 HTML 属性,例如获取标准 HTML 属性的“原始值”,如
<input value="abc">.
解决方案 12:
attributes
-> HTML
properties
DOM 对象
解决方案 13:
在 jQuery 1.6 之前,该attr()
方法有时会在检索属性时考虑属性值,这会导致相当不一致的行为。
该方法的引入prop()
提供了一种在检索属性的同时明确检索属性值的方法.attr()
。
文档:
jQuery.attr()
获取匹配元素集合中第一个元素的属性值。
jQuery.prop()
获取匹配元素集合中第一个元素的属性值。
解决方案 14:
有一件事.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]
(都不会.data('custom-attribute')
影响此选择器)
解决方案 15:
温馨提示一下使用方法prop()
,例如:
if ($("#checkbox1").prop('checked')) {
isDelete = 1;
} else {
isDelete = 0;
}
上面的函数用于检查 checkbox1 是否被选中,如果被选中:返回 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返回空字符串(正确)。
解决方案 16:
关于 prop() 与 attr() 还有一些注意事项:
selectedIndex、tagName、nodeName、nodeType、ownerDocument、defaultChecked 和 defaultSelected 等应使用 .prop() 方法进行检索和设置。这些没有相应的属性,只是属性。
对于输入类型复选框
.attr('checked') //returns checked
.prop('checked') //returns true
.is(':checked') //returns true
prop 方法返回 checked、selected、disabled、readOnly 等的布尔值,而 attr 返回定义的字符串。因此,您可以在 if 条件中直接使用 .prop('checked')。
.attr() 在内部调用 .prop(),因此 .attr() 方法会比直接通过 .prop() 访问它们稍微慢一些。
解决方案 17:
1) 属性 (property) 位于 DOM 中;属性 (attribute) 位于解析到 DOM 中的 HTML 中。
2)$( elem ).attr( "checked" ) (1.6.1+) "checked" (字符串) 将随复选框状态而改变
3) $( elem ).attr( "checked" ) (1.6 之前版本) true (布尔值) 随复选框状态改变
我们主要想使用 DOM 对象而不是类似的自定义属性
data-img, data-xyz
。checkbox
访问值时也存在一些差异,并且href
随着DOM 输出的变化而变化,
以及复选框的
完整链接attr()
`prop()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>
Run code snippetHide resultsExpand snippet
解决方案 18:
如果代码是这样写的,Gary Hole 的答案对于解决问题非常相关
obj.prop("style","border:1px red solid;")
由于 prop 函数返回CSSStyleDeclaration
对象,上述代码在某些浏览器中无法正常工作(IE8 with Chrome Frame Plugin
在我的情况下经过测试)。
因此将其更改为以下代码
obj.prop("style").cssText = "border:1px red solid;"
解决了问题。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件