.prop() vs .attr()

2022-08-29 21:53:39

所以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>

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

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


答案 1

2012 年 11 月 1 日更新

我最初的答案特别适用于jQuery 1.6。我的建议保持不变,但jQuery 1.6.1稍微改变了一些事情:面对预测的一堆破碎的网站,jQuery团队attr()恢复到接近(但不完全相同)的布尔属性的旧行为。John Resig也在博客上发表了关于此事的文章。我可以看到他们遇到的困难,但仍然不同意他的建议。attr()

原始答案

如果您只使用过jQuery而不是直接使用DOM,这可能是一个令人困惑的更改,尽管这在概念上绝对是一个改进。对于使用jQuery的大量网站来说,这并不是那么好,这些网站会因为这种变化而中断。

我将总结主要问题:

  • 您通常想要而不是 .prop()attr()
  • 在大多数情况下,做以前做的事情。在代码中将 to 替换为 通常有效。prop()attr()attr()prop()
  • 属性通常比属性更易于处理。特性值只能是字符串,而属性可以是任何类型。例如,属性是布尔值,属性是具有每个样式的单独属性的对象,属性是数字。checkedstylesize
  • 如果属性和具有相同名称的属性都存在,通常更新一个属性会更新另一个属性,但对于输入的某些属性,情况并非如此,例如和 :对于这些属性,属性始终表示当前状态,而属性(旧版本的IE除外)对应于输入的默认值/检查度(反映在/属性中)。valuecheckeddefaultValuedefaultChecked
  • 此更改删除了一些卡在特性和属性前面的魔术jQuery层,这意味着jQuery开发人员将不得不学习一些关于属性和特性之间的区别。这是一件好事。

如果你是一个jQuery开发人员,并且对整个关于属性和属性的业务感到困惑,你需要退后一步,了解一下,因为jQuery不再那么努力地保护你免受这些东西的影响。对于这个主题的权威但有些枯燥的词,有规格:DOM4HTML DOMDOM Level 2DOM 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") ) {...}

这实际上是世界上最容易与布尔属性有关的事情,自1995年以来,布尔属性在每个主要的可脚本化浏览器中都存在并完美地工作:checked

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”属性获取其初始值,但它的值并不完全相同; 从“类”属性)。其他属性以其他方式获取其初始值:例如,该属性根据其父元素的内容获取其值;元素始终具有属性,无论它是否具有“style”属性。valuehrefclassNameparentNodestyle

让我们在以下页面中考虑这个锚点: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 规范中列出:

这些规范具有出色的索引,我建议将指向它们的链接放在手边;我一直在使用它们。

例如,自定义属性将包括您可能放在元素上以向代码提供元数据的任何属性(现在,只要您坚持使用前缀,该属性自HTML5起就有效)。(最新版本的jQuery允许您通过该函数访问元素,但该函数不仅仅是属性的访问器[它的作用更多,也不小于此];除非您确实需要其功能,否则我会使用该函数与属性进行交互。data-xyzdata-data-xyzdatadata-xyzattrdata-xyz

该函数曾经有一些复杂的逻辑,围绕着获取他们认为你想要的东西,而不是从字面上获取属性。它把这些概念混为一谈。移动到并意味着将它们去混淆。简而言之,在v1.6.0中,jQuery在这方面走得太远了,但是功能很快就被添加回去,以处理人们在技术上应该使用时使用的常见情况。attrpropattrattrattrprop