首页 文章

.prop()vs .attr()

提问于
浏览
2115

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

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

18 回答

  • 636

    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() 作为 origin 的完整链接和 Boolean 值的复选框 (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>
    
  • 2

    我想Tim said it quite well,但让我们退后一步:

    DOM元素是一个对象,一个在内存中的东西 . 与OOP中的大多数对象一样,它具有属性 . 它还单独包含元素上定义的属性的映射(通常来自浏览器读取以创建元素的标记) . 某些元素的属性从具有相同或相似名称的属性获取其初始值( value 从"value"属性获取其初始值; href 从"href"属性获取其初始值,但它不是完全相同的值; className 来自"class"属性) . 其他属性以其他方式获取其初始值:例如, parentNode 属性根据其父元素获取其值;元素始终具有 style 属性,无论它是否具有"style"属性 .

    让我们在 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 可以看出,映射并不总是直接的"pass the value on",有时会涉及到解释 .

    当我谈到属性是对象的属性时,我不是在抽象地说 . 这是一些非jQuery代码:

    var link = document.getElementById('fooAnchor');
    alert(link.href);                 // alerts "http://example.com/foo.html"
    alert(link.getAttribute("href")); // alerts "foo.html"
    

    (这些值与大多数浏览器一样;有一些变化 . )

    link 对象是真实的,您可以看到在它上面访问属性和访问属性之间存在真正的区别 .

    正如蒂姆所说, vast majority 当时,我们希望与 properties 合作 . 部分原因是因为它们的值(甚至是它们的名称)在浏览器中往往更加一致 . 我们大多只希望在没有与之相关的属性(自定义属性)时使用属性,或者当我们知道对于该特定属性时,属性和属性不是1:1(与上面的 href 和"href"一样) .

    标准属性在各种DOM规范中列出:

    这些规格有很好的索引,我建议保持链接方便;我一直都在使用它们 .

    例如,自定义属性包括您可能放置在元素上的任何 data-xyz 属性,以便为您的代码提供元数据(现在,只要您坚持使用 data- 前缀,该属性就像HTML5一样有效) . (jQuery的最新版本允许您通过 data 函数访问 data-xyz 元素,但该函数是 not 只是 data-xyz 属性的访问者[它做得越来越少];除非你真的需要它的功能,我会使用 attrdata-xyz 属性交互的函数 . )

    attr 函数曾经有一些复杂的逻辑来获得他们想要的东西,而不是字面上得到属性 . 它混淆了这些概念 . 移至 propattr 意味着将它们解除混淆 . 简单地说,在v1.6.0中,jQuery在这方面走得太远了,但功能was quickly added backattr 来处理人们使用 attr 的常见情况,技术上他们应该使用 prop .

  • 49

    jQuery已经有很长一段时间了 . 多年来,他们一直满足于一个名为 attr() 的函数,该函数主要检索DOM属性,而不是您期望从名称中获得的结果 . attr()prop()的隔离应该有助于缓解HTML属性和DOM属性之间的一些混淆 . $.fn.prop() 抓取指定的DOM属性,而 $.fn.attr() 抓取指定的HTML属性 .

    为了完全理解它们是如何工作的,这里是对HTML属性和DOM属性之间差异的扩展解释:

    HTML属性

    语法:

    <body onload="foo()">

    Purpose: 允许标记具有与之关联的数据,以用于事件,呈现和其他目的 .

    Visualization:
    HTML Attributes
    此属性显示在正文中 . 它可以通过以下代码访问:

    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;

    Purpose: 允许访问属于元素节点的属性 . 这些属性与属性类似,但只能通过JavaScript访问 . 这是一个重要的区别,有助于阐明DOM属性的作用 . Please note that attributes are completely different from properties ,因为这个事件处理程序赋值是无用的并且赢得't receive the event (body doesn' t有一个onload事件,只有一个onload属性) .

    Visualization:
    DOM Properties

    在这里,您将注意到Firebug中“DOM”选项卡下的属性列表 . 这些是DOM属性 . 你会立即注意到它们中的一些,因为你以前在不知情的情况下使用过它们 . 他们的 Value 观是你通过JavaScript获得的 .

    文档

    示例

    HTML: <textarea id="test" value="foo"></textarea>

    JavaScript: alert($('#test').attr('value'));

    在早期版本的jQuery中,这将返回一个空字符串 . 在1.6中,它返回正确的值 foo .

    在没有浏览任何一个函数的新代码的情况下,我可以充满信心地说,混淆更多地与HTML属性和DOM属性之间的差异有关,而不是与代码本身有关 . 希望这能为你解决一些问题 .

    -Matt

  • 7

    只是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' 呃?为什么不"pear"因为这是在该元素上设置的最后一个 . 因为属性是在输入属性上更改的,而不是DOM输入元素本身 - 它们基本上几乎彼此独立工作 .

    • $('input').prop('blah') :返回 'pear'

    由于上述原因,你真正需要注意的事情只是 do not mix the usage of these for the same property throughout your application .

    See a fiddle demonstrating the difference: http://jsfiddle.net/garreh/uLQXc/


    .attr vs .prop:

    第1轮:风格

    <input style="font:arial;"/>
    
    • .attr('style') - 返回匹配元素的内联样式,即 "font:arial;"

    • .prop('style') - 返回样式声明对象,即 CSSStyleDeclaration

    第2轮: Value

    <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')

  • 237

    TL;DR

    在大多数情况下,使用 prop() 覆盖 attr() .

    属性是input元素的当前状态 . 属性是默认值 .

    属性可以包含不同类型的东西 . 属性只能包含字符串

  • 13

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

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

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

    从而将其更改为以下代码

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

    解决了这个问题 .

  • 26

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

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

    • 获取不与DOM属性同步的HTML属性,例如获取标准HTML属性的"original value",如 <input value="abc">.

  • 18

    一切都在文档中:

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

    所以使用道具!

  • 6

    Update 1 November 2012

    我的原始答案特别适用于jQuery 1.6 . 我的建议仍然是相同的,但jQuery 1.6.1略有改变:面对预测的一堆破碎的网站,jQuery团队reverted attr() to something close to (but not exactly the same as) its old behaviour for Boolean attributes . John Resig也是blogged about it . 我可以看到他们遇到的困难,但仍然不同意他更喜欢 attr() 的建议 .

    Original answer

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

    我将总结一下主要问题:

    • 您通常需要 prop() 而不是 attr() .

    • 在大多数情况下, prop() 会做 attr() 曾经做过的事情 . 在代码中用 prop() 替换 attr() 的调用通常会起作用 .

    • 属性通常比属性更易于处理 . 属性值可以只是一个字符串,而属性可以是任何类型 . 例如, checked 属性是布尔值, style 属性是每个样式具有单独属性的对象, size 属性是数字 .

    • 如果存在属性和具有相同名称的属性,通常更新一个将更新另一个,但输入的某些属性不是这种情况,例如 valuechecked :对于这些属性,属性始终表示当前属性状态,而属性(IE的旧版本除外)对应于输入的默认值/ checkedness(反映在 defaultValue / defaultChecked 属性中) .

    • 这个更改删除了一些在属性和属性前面停留的魔法jQuery层,这意味着jQuery开发人员必须要了解属性和属性之间的区别 . 这是件好事 .

    如果你're a jQuery developer and are confused by this whole business about properties and attributes, you need to take a step back and learn a little about it, since jQuery is no longer trying so hard to shield you from this stuff. For the authoritative but somewhat dry word on the subject, there' s规格:DOM4HTML DOMDOM Level 2DOM Level 3 . Mozilla的DOM文档对大多数现代浏览器都有效,并且比规范更容易阅读,因此您可能会发现它们有用DOM reference . 有一个section on element properties .

    作为属性如何比属性更易于处理的示例,请考虑最初检查的复选框 . 以下是两个可能的有效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 属性来编写复选框脚本的想法是无益的,也是不必要的 . 该 properties 是您所需要的 .

    • 检查或取消选中复选框的正确方法是使用 checked 属性并不明显

    • 属性值反映默认值而不是当前可见状态(除了IE的某些旧版本,因此使事情变得更加困难) . 该属性不会告诉您是否选中了页面上的复选框 . 见http://jsfiddle.net/VktA6/49/ .

  • -2

    .attr()

    • 获取匹配元素集中第一个元素的 attribute 的值 .

    • 为您提供元素的值,因为它是在页面加载的html中定义的

    .prop()

    • 获取匹配元素集中第一个元素的 property 的值 .

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

  • 0

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

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

    文件:

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

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

  • 32

    .prop()

    .prop(propertyName)
    propertyName的
    类型:字符串
    要获取的属性的名称 .
    .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
    类型:字符串
    要获取的属性的名称 .
    .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>
    
  • 0

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

    重要的是,其中许多是同步的(如果更新 class 属性,html中的 class 属性也将更新;否则) . But 某些属性可能会同步到意外的属性 - 例如, 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() 据说比 .attr() 快约2.5倍 .

  • 1774

    attributes - > HTML

    properties - > DOM

  • 240

    Dirty checkedness

    这个概念提供了一个可以观察到差异的例子: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>
    

    对于某些属性,如 disabledbutton ,添加或删除内容属性 disabled="disabled" 始终切换属性(在HTML5中称为IDL属性),因为http://www.w3.org/TR/html5/forms.html#attr-fe-disabled说:

    禁用的IDL属性必须反映已禁用的内容属性 .

    所以你可能会侥幸逃脱它,虽然它很难看,因为它不需要修改HTML .

    对于 input type="checkbox" 上的 checked="checked" 等其他属性,事情会中断,因为一旦点击它就会变脏,然后添加或删除 checked="checked" 内容属性 does not toggle checkedness anymore .

    这就是为什么你应该主要使用 .prop ,因为它直接影响有效属性,而不是依赖于修改HTML的复杂副作用 .

  • 2

    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将被替换为道具 .

    希望能帮助到你 .

  • 134

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

    更多细节

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

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

    示例:当您的标记没有 class 属性时,DOM属性 className 确实存在,其字符串值为空 .

    edit

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

  • 35

    轻轻提醒一下使用 prop() ,例如:

    if ($("#checkbox1").prop('checked')) {
        isDelete = 1;
    } else {
        isDelete = 0;
    }
    

    上面的函数用于检查checkbox1是否被选中,如果选中:return 1;如果不是:返回0.函数prop()在这里用作GET函数 .

    if ($("#checkbox1").prop('checked', true)) {
        isDelete = 1;
    } else {
        isDelete = 0;
    }
    

    上面的函数用于设置要检查的checkbox1并始终返回1.现在函数prop()用作SET函数 .

    Don't mess up.

    P / S:当我检查Image src 属性时 . 如果 src 为空, prop 将返回页面的当前URL(错误), attr 返回空字符串(右) .

相关问题