.prop() 与 .attr()

2024-11-02 21:00:00
admin
原创
36
摘要:问题描述:所以jQuery 1.6有了这个新功能prop()。$(selector).click(function(){ //instead of: this.getAttribute('style'); //do i use: $(this...

问题描述:

所以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为字符串,但将 打印propCSSStyleDeclaration,为什么?这会对我以后的编码产生什么影响?


解决方案 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`hrefclassNameparentNode`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函数过去有一些复杂的逻辑,用于获取他们认为您想要的内容,而不是直接获取属性。它混淆了概念。移至propattr旨在消除它们之间的混淆。在 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()">

目的:
允许标记拥有与其关联的数据,用于事件、渲染和其他目的。

可视化:
HTML 属性
此处主体上显示了类属性。可通过以下代码访问:

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 属性)。

可视化:
DOM 属性

在这里,您会注意到 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">
  1. $('input').attr('blah')'hello'按预期返回。这里没有什么意外。

  2. $('input').prop('blah'): 返回undefined-- 因为它试图这样做[HTMLInputElement].blah-- 但该 DOM 对象上不存在这样的属性。它仅作为该元素的属性存在于范围内,即[HTMLInputElement].getAttribute('blah')

现在我们改变一些事情,如下所示:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): 返回的'apple'是 eh?为什么不是“pear”,因为这是在该元素上最后设置的。因为属性是在输入属性上更改的,而不是 DOM 输入元素本身——它们基本上几乎彼此独立工作。

  2. $('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展开片段

对于某些属性(例如disabledon )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 意义上某个对象的实际属性)。

重要的是,它们中的许多都是同步的(如果你更新classproperty ,classhtml 中的 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(),而后者是官方建议的?

  1. .prop()可以返回任何类型 - 字符串,整数,布尔值;而.attr()始终返回字符串。

  2. .prop()据说比 快 约 2.5 倍.attr()

解决方案 10:

.attr()

  • 获取匹配元素集合中第一个元素的属性值。

  • 为您提供页面加载时在 html 中定义的元素值

.prop()

  • 获取匹配元素集合中第一个元素的属性值。

  • 提供通过 javascript/jquery 修改的元素的更新值

解决方案 11:

通常情况下,您需要使用属性。仅将属性用于:

  1. 获取自定义 HTML 属性(因为它未与 DOM 属性同步)。

  2. 获取与 DOM 属性不同步的 HTML 属性,例如获取标准 HTML 属性的“原始值”,如<input value="abc">.

解决方案 12:

attributes-> HTML

propertiesDOM 对象

解决方案 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;"

解决了问题。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用