.prop() vs .attr()

30 浏览
0 Comments

.prop() vs .attr()

所以 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 后停止工作吗?

更新

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);
});


test

(查看这个 jsfiddle: http://jsfiddle.net/maniator/JpUF2/

控制台将 getAttributeattr 记录为字符串,但将 prop 记录为 CSSStyleDeclaration,为什么?这将如何影响我未来的编码?

admin 更改状态以发布 2023年5月21日
0
0 Comments

我认为 Tim表达得很好,但我们先回到基本概念:

DOM 元素是一个对象,是内存中的事物。和大多数 OOP 中的对象一样,它有属性。另外,它还有一个定义在元素上的属性映射(通常来自浏览器用于创建元素的标记语言)。元素的某些属性从具有相同或类似名称的属性中获取初始值(如value从"value"属性中获取初始值; href从 "href"属性中获取初始值,但不是完全相同的值; className从 "class"属性获取)。其他属性以其他方式获得它们的初始值:例如,parentNode属性基于其父元素而取值; 一个元素始终具有style属性,无论它是否具有 "style"属性。

考虑一个页面上的锚点http://example.com/testing.html

Hi

一些任意的 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时,才使用属性。

标准属性是在各种DOM规范中进行布局:

这些规范都有很好的索引,我建议随时保留与它们的链接;我一直使用它们。

自定义属性可以包括您可能放置在元素上的任何data-xyz属性,以向您的代码提供元数据(现在在HTML5中是有效的,只要您坚持使用data-前缀)。 (最近版本的jQuery通过data函数使您可以访问data-xyz元素,但是该函数不仅仅是访问data-xyz属性[它会执行更多或更少的操作],除非您实际需要它的功能,否则我会使用attr函数与data-xyz属性交互。)

attr 函数曾经在获取它们认为您想要的内容方面具有一些复杂的逻辑,而不是逐字获取属性。 它混淆了这些概念。转向propattr旨在解决它们之间的紧密联系。在jQuery的v1.6.0中,短暂地走得太远了,但是功能很快就被新增回来,以处理人们在技术上应该使用prop而使用attr的常见情况。

0
0 Comments

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属性是一个数字。
  • 如果存在具有相同名称的属性和属性,则通常更新一个将更新另一个,但对于输入的某些属性(如valuechecked),情况并非如此:对于这些属性,属性始终表示当前状态,而属性(除了旧版本的IE之外)对应于输入的默认值/选中状态(反映在defaultValue / defaultChecked属性中)。
  • 此更改消除了jQuery固定在属性和属性前面的一些神奇层,意味着jQuery开发人员将不得不了解属性和属性之间的区别。这是一件好事。

如果您是jQuery开发人员,并且对于属性和属性整个业务感到困惑,那么您需要退后一步,并学习一些相关知识,因为jQuery不再尝试如此努力地保护您的代码。对于主题的官方,但有点枯燥的话,有规范:DOM4HTML DOMDOM Level 2DOM Level 3。Mozilla的DOM文档适用于大多数现代浏览器,并且比规范更易于阅读,因此您可能会发现他们的DOM参考有所帮助。有一个有关元素属性的部分

举个例子来说,属性比属性更简单易处理。考虑一个最初被选中的复选框,这里是两种可能的有效的HTML代码:



那么用jQuery如何找出是否选中复选框呢?在Stack Overflow上,你通常会找到以下建议:

  • 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/
0