javascript - prop用法 - prop attr




.prop()vs.attr() (12)

1)属性在DOM中; HTML中的属性被解析为DOM。

2)$(elem).attr(“checked”)(1.6.1+)“checked”(字符串)将随复选框状态而变化

3)$(elem).attr(“checked”)(pre-1.6)true(布尔值)更改为复选框状态

  • 我们通常希望使用DOM对象而不是自定义属性data-img, data-xyz

  • 在访问checkbox值时也有一些区别hrefattr()并且prop()随着DOM输出的变化,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>

所以jQuery 1.6有新的函数prop()

$(selector).click(function(){
    //instead of:
    this.getAttribute('style');
    //do i use:
    $(this).prop('style');
    //or:
    $(this).attr('style');
})

或者在这种情况下,他们做同样的事情?

如果我必须切换到使用prop() ,如果我切换到1.6,所有旧的attr()调用都将中断?

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>

(另见这个小提琴: http://jsfiddle.net/maniator/JpUF2/http://jsfiddle.net/maniator/JpUF2/

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


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


attributes - > HTML

properties - > DOM


2012年11月1日更新

我的原始答案特别适用于jQuery 1.6。 我的建议仍然相同,但jQuery 1.6.1略有改变:面对预测的一堆破碎的网站,jQuery团队将attr()恢复为接近(但不完全相同)布尔属性的旧行为 。 John Resig也在博客上写了这篇文章 。 我可以看到他们遇到的困难,但仍然不同意他更喜欢attr()建议。

原始答案

如果您只使用过jQuery而不是直接使用DOM,那么这可能是一个令人困惑的变化,尽管它在概念上肯定是一种改进。 对于使用jQuery的网站来说,这不太好,但是由于这种变化会破坏。

我将总结一下主要问题:

  • 你通常需要prop()而不是attr()
  • 在大多数情况下, prop()执行attr()过去做的事情。 在代码中用prop()替换对attr()调用通常会起作用。
  • 属性通常比属性更容易处理。 属性值可以只是一个字符串,而属性可以是任何类型。 例如, checked属性是一个布尔值, style属性是一个对象,每个样式都有各自的属性, size属性是一个数字。
  • 如果存在属性和具有相同名称的属性,通常更新一个将更新另一个,但输入的某些属性不是这种情况,例如valuechecked :对于这些属性,该属性始终表示当前状态而属性(IE的旧版本除外)对应于输入的默认值/ checkedness(反映在defaultValue / defaultChecked属性中)。
  • 这个更改删除了一些在属性和属性前面停留的魔法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") ) {...}

这实际上是世界上最简单的事情,使用经过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/

。支柱()

.prop( propertyName )
propertyName
Type: String
The name of the property to get.

.prop()方法仅获取匹配集中第一个元素的属性值。它为尚未设置的属性的值返回undefined,或者匹配的set没有元素。要单独获取每个元素的值,请使用循环结构,例如jQuery的.each()或.map()方法。

<html>
<head>
  <meta charset="utf-8">
  <title>prop demo</title>
  <style>
  p {
    margin: 20px 0 0;
  }
  b {
    color: blue;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</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>

.attr()

.attr( attributeName )
attributeName
Type: String
The name of the attribute to get.

.attr()方法仅获取匹配集中第一个元素的属性值。要单独获取每个元素的值,请使用循环结构,例如jQuery的.each()或.map()方法。

使用jQuery的.attr()方法获取元素属性的值有两个主要好处:

方便:它可以直接在jQuery对象上调用,并链接到其他jQuery方法。跨浏览器一致性:某些属性的值在浏览器之间报告不一致,甚至在单个浏览器的版本中也是如此。.attr()方法减少了这种不一致。

<html>
<head>
  <meta charset="utf-8">
  <title>attr demo</title>
  <style>
  em {
    color: blue;
    font-weight: bold;
  }
  div {
    color: red;
  }
  </style>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<p>Once there was a <em title="huge, gigantic">large</em> dinosaur...</p>

The title of the emphasis is:<div></div>

<script>
var title = $( "em" ).attr( "title" );
$( "div" ).text( title );
</script>

</body>
</html>

属性在HTML 文本文档/文件中 (==想象这是解析html标记的结果),而
属性在HTML DOM树中 (==基本上是JS意义上某个对象的实际属性)。

重要的是,它们中的许多都是同步的(如果更新class属性,html中的class属性也将被更新;否则)。 但是某些属性可能会同步到意外的属性 - 例如,已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(),后者是官方建议的?

  1. .prop()可以返回任何类型 - 字符串,整数,布尔值; 而.attr()总是返回一个字符串。
  2. .prop().attr()快约2.5倍。

jQuery 1.6引入了.prop()函数并分离了DOM属性和属性,它引发了很多关于.attr和.prop函数之间差异的问题。

见下面的例子:

例如:1)

<input id="demo" type="text" dbvalue="Kansagara" />

$("#demo").attr("dbvalue");   // returns Kansagara
$("#demo").prop("dbvalue");   // returns undefined

.prop()只返回HTML DOM属性的值,它没有返回自定义属性的值,而.attr()也返回如上所示的自定义属性值。

实施例:2)

<input id="demo" type="text" value="Kansagara" />

现在,我在文本框中将文本'Kansagara'更改为'Hitesh'。

$("#demo").attr("value");   // returns Kansagara
$("#demo").prop("value");   // returns Hitesh

现在你已经知道这意味着什么。只更改了元素的属性,因为它在DOM中是动态的。但元素的属性是HTML文本,无法更改。从广义上讲,属性总是表示当前状态,而属性(IE的旧版本除外)表示初始状态或者是html属性,因为它们是严格定义的。该属性不会告诉您当前状态。

一个复选框(jquery 1.6+)

<input id="check1" checked="checked" type="checkbox" />

.attr('checked') //returns  checked
.prop('checked') //returns  true
.is(':checked') //returns true

prop方法返回checked,selected,disabled,readOnly..etc的布尔值,而attr返回已定义的字符串。因此,您可以在if条件下直接使用.prop('checked')。

.attr()在内部调用.prop(),因此.attr()方法比直接通过.prop()访问它们要慢一些。

对于jQuery 1.6+,将主要使用prop,因为它比attr简单且宽泛。在大多数旧项目中,attr用于获取元素的当前状态信息。但是现在道具已经完成了这项工作,并且attr将被替换为道具。

希望能帮助到你。


一切都在文档中:

在特定情况下,属性和属性之间的差异可能很重要。 在jQuery 1.6之前,.attr()方法有时在检索某些属性时会考虑属性值,这可能会导致行为不一致。 从jQuery 1.6开始,.prop()方法提供了一种显式检索属性值的方法,而.attr()只检索属性。

所以使用道具!


如果代码以这种方式编写,Gary Hole的答案与解决问题非常相关

obj.prop("style","border:1px red solid;")

由于prop函数返回CSSStyleDeclaration对象,上面的代码在某些浏览器中无法正常工作(IE8 with Chrome Frame Plugin在我的情况下测试)。

从而将其更改为以下代码

obj.prop("style").cssText = "border:1px red solid;"

解决了这个问题。


属性在DOM中; HTML中的属性被解析为DOM。

更多细节

如果更改属性,则更改将反映在DOM中(有时使用不同的名称)。

示例:更改标记的class属性将更改DOM中该标记的className属性。 如果标记上没有属性,则仍具有相应的DOM属性,其属性为空或默认值。

示例:虽然您的标记没有class属性,但DOM属性className确实存在,其字符串值为空。

编辑

如果更改一个,另一个将由控制器更改,反之亦然。 这个控制器不在jQuery中,而是在浏览器的本机代码中。


通常你会想要使用属性。 仅将属性用于:

  1. 获取自定义HTML属性(因为它未与DOM属性同步)。
  2. 获取不与DOM属性同步的HTML属性,例如获取标准HTML属性的“原始值”,例如 <input value="abc">.

在jQuery 1.6之前,该attr()方法有时在检索属性时考虑属性值,这会导致相当不一致的行为。

prop()方法的引入提供了一种显式检索属性值的方法,同时.attr()检索属性。

文件:

jQuery.attr() 获取匹配元素集中第一个元素的属性值。

jQuery.prop() 获取匹配元素集中第一个元素的属性值。





prop