.prop () vs .attr ()

2301

Donc jQuery 1.6 a la nouvelle fonction prop().

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

ou dans ce cas font-ils la même chose?

Et si je dois passer à l'utilisation prop(), tous les anciens attr()appels seront interrompus si je passe à 1.6?

MISE À JOUR

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>

(voir aussi ce violon: http://jsfiddle.net/maniator/JpUF2/ )

La console enregistre en getAttributetant que chaîne et en attrtant que chaîne, mais en proptant que CSSStyleDeclaration, pourquoi? Et comment cela affectera-t-il mon codage à l'avenir?

Naftali aka Neal
la source
17
Ce sera d'un intérêt certain: books.google.ca/…
28
@Neal, c'est parce que ce changement transcende jQuery. La différence entre les attributs HTML et les propriétés DOM est énorme.
7
Cela me rend triste de voir que jQuery a annulé les changements. Ils vont dans la mauvaise direction.
4
@Neal. Oui, et cela complique encore le problème au lieu de séparer les deux méthodes.
6
@BritishDeveloper la réponse est plus compliquée que de simplement indiquer toujours utiliser x ou y car cela dépend de ce que vous avez l'intention d'obtenir. Voulez-vous l'attribut ou voulez-vous la propriété? ce sont deux choses très différentes.
Kevin B

Réponses:

1876

Mise à jour 1 novembre 2012

Ma réponse originale s'applique spécifiquement à jQuery 1.6. Mon conseil reste le même mais jQuery 1.6.1 a légèrement changé les choses: face à la pile prédite de sites Web cassés, l'équipe jQuery est revenue attr()à quelque chose de proche (mais pas exactement le même que) son ancien comportement pour les attributs booléens . John Resig a également blogué à ce sujet . Je peux voir la difficulté dans laquelle ils se trouvaient, mais je suis toujours en désaccord avec sa recommandation de préférer attr().

Réponse originale

Si vous n'avez utilisé que jQuery et pas le DOM directement, cela pourrait être un changement déroutant, bien qu'il s'agisse définitivement d'une amélioration conceptuelle. Pas si bon pour les bazillions de sites utilisant jQuery qui se briseront à la suite de ce changement.

Je vais résumer les principaux problèmes:

  • Vous voulez généralement prop()plutôt que attr().
  • Dans la majorité des cas, prop()fait ce qu'il attr()faisait. Remplacer les appels à attr()par prop()dans votre code fonctionne généralement.
  • Les propriétés sont généralement plus simples à gérer que les attributs. Une valeur d'attribut ne peut être qu'une chaîne alors qu'une propriété peut être de n'importe quel type. Par exemple, la checkedpropriété est un booléen, la stylepropriété est un objet avec des propriétés individuelles pour chaque style, la sizepropriété est un nombre.
  • Lorsqu'il existe à la fois une propriété et un attribut du même nom, la mise à jour de l'un mettra généralement à jour l'autre, mais ce n'est pas le cas pour certains attributs d'entrées, tels que valueet checked: pour ces attributs, la propriété représente toujours l'état actuel tandis que le L'attribut (sauf dans les anciennes versions d'IE) correspond à la valeur / vérification par défaut de l'entrée (reflétée dans la propriété defaultValue/ defaultChecked).
  • Cette modification supprime une partie de la couche de jQuery magique coincée devant les attributs et les propriétés, ce qui signifie que les développeurs de jQuery devront en apprendre un peu plus sur la différence entre les propriétés et les attributs. C'est une bonne chose.

Si vous êtes un développeur jQuery et que toute cette entreprise est confuse à propos des propriétés et des attributs, vous devez prendre du recul et en apprendre un peu plus, car jQuery n'essaie plus si fort de vous protéger de ce genre de choses. Pour le mot faisant autorité mais un peu sec sur le sujet, il y a les spécifications: DOM4 , HTML DOM , DOM niveau 2 , DOM niveau 3 . La documentation DOM de Mozilla est valide pour la plupart des navigateurs modernes et est plus facile à lire que les spécifications, vous pouvez donc trouver leur référence DOM utile. Il y a une section sur les propriétés des éléments .

Pour illustrer la façon dont les propriétés sont plus simples à gérer que les attributs, considérons une case à cocher initialement cochée. Voici deux éléments HTML valides possibles pour ce faire:

<input id="cb" type="checkbox" checked>
<input id="cb" type="checkbox" checked="checked">

Alors, comment savoir si la case est cochée avec jQuery? Regardez sur Stack Overflow et vous trouverez généralement les suggestions suivantes:

  • if ( $("#cb").attr("checked") === true ) {...}
  • if ( $("#cb").attr("checked") == "checked" ) {...}
  • if ( $("#cb").is(":checked") ) {...}

C'est en fait la chose la plus simple au monde à faire avec la checkedpropriété booléenne, qui existe et fonctionne parfaitement dans tous les principaux navigateurs scriptables depuis 1995:

if (document.getElementById("cb").checked) {...}

La propriété rend également cocher ou décocher la case triviale:

document.getElementById("cb").checked = false

Dans jQuery 1.6, cela devient sans ambiguïté

$("#cb").prop("checked", false)

L'idée d'utiliser l' checkedattribut pour écrire une case à cocher est inutile et inutile. La propriété est ce dont vous avez besoin.

  • Il n'est pas évident quelle est la bonne façon de cocher ou décocher la case en utilisant l' checkedattribut
  • La valeur de l'attribut reflète l'état par défaut plutôt que l'état visible actuel (sauf dans certaines anciennes versions d'IE, ce qui rend les choses encore plus difficiles). L'attribut ne vous indique pas si la case à cocher de la page est cochée. Voir http://jsfiddle.net/VktA6/49/ .
Tim Down
la source
2
@TJCrowder, alors lesquels?
Naftali aka Neal
9
@Neal: Si vous voulez savoir quelles sont les propriétés des éléments DOM ont et comment des attributs peuvent semer leurs valeurs, garder ces liens à la main: La spécification HTML DOM2 , la DOM2 spécifications et DOM3 spécifications. Les index dans chaque cas sont excellents et vous lient directement à une description complète de la propriété, d'où sa valeur vient, etc.
TJ Crowder
4
@Neal: ce qui le rend différent: la source et la nature des informations. Regardez l' valueexemple de Tim , par exemple. Une fonction appelée attrqui récupère la propriété value plutôt que l'attribut "valeur" n'a pas beaucoup de sens (et ils peuvent être différents). À l'avenir, attrfaire des attributs et propfaire des propriétés sera plus clair, même si la transition sera pénible pour certains. Ne prenez pas cela dans le mauvais sens, rien de tel que de prendre du recul et de lire les spécifications pour avoir une idée de ce que sont les propriétés.
TJ Crowder
54
@Neal: Un élément DOM est un objet. Les propriétés sont les propriétés de cet objet, comme tout autre objet de programmation. Certains de ces accessoires tirent leurs valeurs initiales des attributs du balisage, qui sont également stockés sur l'objet DOM dans une carte d'attributs distincte . Dans la plupart des cas, l'écriture dans un accessoire ne fait que modifier l'accessoire, bien qu'il y ait malheureusement certains accessoires qui écrivent les modifications dans l'attr sous-jacent ( valuepar exemple), mais essayons d'ignorer la plupart du temps. 99% du temps, vous voulez travailler avec des accessoires. Si vous devez travailler avec un attribut réel, vous le saurez probablement.
TJ Crowder
4
@Tim: "Changer la valuepropriété d'une entrée ne change pas son valueattribut dans les navigateurs modernes" Je ne le pensais pas, c'est pourquoi j'ai commencé à l'utiliser comme exemple, mais quand j'ai commencé à coder l'exemple, sacrément s'il n'a pas été mis à jour sur Chrome, Firefox, Opera, IE ... - jsbin.com/ahire4 Il s'avère que c'est parce que j'utilisais un input[type="button"]pour mon expérience. Il ne met pas à jour l'attribut sur un input[type="text"]- jsbin.com/ahire4/2 Parlez de compliqué !! Pas seulement l'élément, mais le type de celui-ci ...
TJ Crowder
664

Je pense que Tim l'a très bien dit , mais revenons en arrière:

Un élément DOM est un objet, une chose en mémoire. Comme la plupart des objets dans la POO, il a des propriétés . Il a également, séparément, une carte des attributs définis sur l'élément (provenant généralement du balisage que le navigateur a lu pour créer l'élément). Certaines propriétés de l'élément tirent leurs valeurs initiales d' attributs portant des noms identiques ou similaires ( valueobtient sa valeur initiale de l'attribut "value"; hrefobtient sa valeur initiale de l'attribut "href", mais ce n'est pas exactement la même valeur; classNamede la attribut "classe"). D'autres propriétés obtiennent leurs valeurs initiales de différentes manières: Par exemple, la parentNodepropriété obtient sa valeur en fonction de son élément parent;style , qu'elle ait ou non un attribut "style".

Considérons cette ancre dans une page à http://example.com/testing.html:

<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>

De l'art ASCII gratuit (et en laissant de côté beaucoup de choses):

+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| HTMLAnchorElement |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
| href: "http://example.com/foo.html" |
| nom: "fooAnchor" |
| id: "fooAnchor" |
| className: "test one" |
| attributs: |
| href: "foo.html" |
| nom: "fooAnchor" |
| id: "fooAnchor" |
| classe: "test one" |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +

Notez que les propriétés et les attributs sont distincts.

Maintenant, bien qu'ils soient distincts, parce que tout cela a évolué plutôt que d'être conçu à partir de zéro, un certain nombre de propriétés réécrivent l'attribut dont elles dérivent si vous les définissez. Mais tous ne le font pas, et comme vous pouvez le voir hrefci-dessus, le mappage n'est pas toujours une simple "transmission de la valeur", parfois une interprétation est impliquée.

Quand je parle de propriétés étant des propriétés d'un objet, je ne parle pas dans l'abstrait. Voici du code non jQuery:

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

(Ces valeurs sont celles de la plupart des navigateurs; il existe certaines variations.)

L' linkobjet est une chose réelle, et vous pouvez voir qu'il y a une réelle distinction entre accéder à une propriété et accéder à un attribut .

Comme l'a dit Tim, la grande majorité du temps, nous voulons travailler avec des propriétés. C'est en partie parce que leurs valeurs (même leurs noms) ont tendance à être plus cohérentes entre les navigateurs. La plupart du temps, nous ne voulons travailler avec des attributs que lorsqu'aucune propriété ne leur est associée (attributs personnalisés), ou lorsque nous savons que pour cet attribut particulier, l'attribut et la propriété ne sont pas 1: 1 (comme avec hrefet "href" ci-dessus) .

Les propriétés standard sont présentées dans les différentes spécifications DOM:

Ces spécifications ont d'excellents index et je recommande de garder les liens à portée de main; Je les utilise tout le temps.

Les attributs personnalisés comprendraient, par exemple, tous les data-xyzattributs que vous pourriez mettre sur des éléments pour fournir des métadonnées à votre code (maintenant que cela est valable en HTML5, tant que vous vous en tenez au data-préfixe). (Les versions récentes de jQuery vous donnent accès aux data-xyzéléments via la datafonction, mais cette fonction n'est pas seulement un accesseur pour les data-xyzattributs [elle fait à la fois plus et moins que cela]; sauf si vous avez réellement besoin de ses fonctionnalités, j'utiliserais la attrfonction pour interagir avec data-xyzattribut.)

La attrfonction avait une logique compliquée pour obtenir ce qu'ils pensaient que vous vouliez, plutôt que d'obtenir littéralement l'attribut. Il a confondu les concepts. Déménager propet attrétait censé les déconfigurer. En bref dans v1.6.0 jQuery est allé trop loin à cet égard, mais la fonctionnalité a été rapidement ajouté à nouveau à attrfaire face aux situations communes où les gens utilisent attrlorsque cela est techniquement , ils devraient utiliser prop.

TJ Crowder
la source
Sensationnel. cette nouvelle mise à jour 1.6.1 annule vraiment un peu cette question .. (mais pas beaucoup) mais ce lien y répond essentiellement maintenant
Naftali aka Neal
Cela ne l'a pas annulé pour moi, j'ai juste corrigé un bogue en utilisant jquery1.7 où je mettais .attr ('class', 'bla') et ça ne fonctionnait pas où .prop ('className', 'bla' ) a fonctionné
PandaWood
@PandaWood: .attr('class', 'bla')fonctionne comme prévu pour moi dans 1.7.0 , 1.7.1 et 1.7.2 sur Chrome 17, Firefox 11, Opera 11, IE6, IE8, IE9 et Safari 5.
TJ Crowder
Merci, il doit y avoir quelque chose de spécifique dans mon cas, laissez-moi vérifier cela et revenir avec un cas de test. Mais changer le code tel que nous l'avons en ce moment, simplement "prop / className", au lieu de "attr" corrige un énorme bogue pour nous qui a frappé lorsque nous sommes passés de jquery1.4 à 1.7 - sur tous les navigateurs
PandaWood
3
@TJCrowder re: .data- il lira la valeur par défaut de l'attribut, s'il est présent, mais si vous l'écrivez, il changera une propriété cachée de l'élément et ne mettra pas à jour l'attribut.
Alnitak
250

Ce changement a été long à venir pour jQuery. Pendant des années, ils se sont contentés d'une fonction nommée attr()qui récupérait principalement les propriétés DOM, pas le résultat que vous attendez du nom. La ségrégation de attr()et prop()devrait aider à atténuer une partie de la confusion entre les attributs HTML et les propriétés DOM. $.fn.prop()saisit la propriété DOM spécifiée, tandis qu'il $.fn.attr()saisit l'attribut HTML spécifié.

Pour bien comprendre comment ils fonctionnent, voici une explication détaillée de la différence entre les attributs HTML et les propriétés DOM:

Attributs HTML

Syntaxe:

<body onload="foo()">

Objectif: permet au balisage d'avoir des données qui lui sont associées pour les événements, le rendu et à d'autres fins.

Visualisation: l' Attributs HTML attribut class est affiché ici sur le corps. Il est accessible via le code suivant:

var attr;
attr = document.body.getAttribute("class");
//IE 8 Quirks and below
attr = document.body.getAttribute("className");

Les attributs sont renvoyés sous forme de chaîne et peuvent être incohérents d'un navigateur à l'autre. Cependant, ils peuvent être essentiels dans certaines situations. Comme illustré ci-dessus, IE 8 Quirks Mode (et ci-dessous) attend le nom d'une propriété DOM dans get / set / removeAttribute au lieu du nom d'attribut. C'est l'une des nombreuses raisons pour lesquelles il est important de connaître la différence.

Propriétés DOM

Syntaxe:

document.body.onload = foo;

Objectif: donne accès aux propriétés appartenant aux nœuds d'élément. Ces propriétés sont similaires aux attributs, mais ne sont accessibles que via JavaScript. Il s'agit d'une différence importante qui permet de clarifier le rôle des propriétés DOM. Veuillez noter que les attributs sont complètement différents des propriétés , car cette affectation de gestionnaire d'événements est inutile et ne recevra pas l'événement (le corps n'a pas d'événement onload, seulement un attribut onload).

Visualisation: Propriétés DOM

Ici, vous remarquerez une liste de propriétés sous l'onglet "DOM" dans Firebug. Ce sont des propriétés DOM. Vous en remarquerez immédiatement un certain nombre, car vous les avez déjà utilisés sans le savoir. Leurs valeurs sont ce que vous recevrez via JavaScript.

Documentation

Exemple

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

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

Dans les versions antérieures de jQuery, cela renvoie une chaîne vide. En 1.6, il renvoie la valeur correcte, foo.

Sans avoir jeté un coup d'œil au nouveau code de l'une ou l'autre fonction, je peux dire avec confiance que la confusion a plus à voir avec la différence entre les attributs HTML et les propriétés DOM qu'avec le code lui-même. J'espère que cela a clarifié certaines choses pour vous.

-Mat

K.Dᴀᴠɪs
la source
7
$.prop()obtient les propriétés DOM, $.attr()obtient les attributs HTML. J'essaie de combler l'écart psychologiquement afin que vous puissiez comprendre la différence entre les deux.
10
Mon garçon, je suis confus maintenant aussi. Alors $('#test').prop('value')ne retourne rien? Ni .attr('checked')pour une case à cocher? Mais avant? Vous devez maintenant le changer en prop('checked')? Je ne comprends pas la nécessité de cette distinction - pourquoi est-il important de faire la différence entre les attributs HTML et les propriétés DOM? Quel est le cas d'utilisation courant qui a fait que ce changement "arrive longtemps" ? Quel est le problème avec l'abstraction de la distinction entre les deux, car il semble que leurs cas d'utilisation se chevauchent principalement?
BlueRaja - Danny Pflughoeft
5
@BlueRaja: car il existe une sérieuse différence sous-jacente entre les deux concepts qui, si vous la frottez sous le tapis comme jQuery le faisait auparavant, entraîne des échecs inattendus. valueest l'un des cas les plus évidents, car la valuepropriété vous donnera la valeur actuelle d'un champ, mais l' valueattribut vous donnera la valeur d'origine qui a été déclarée dans l' value="..."attribut, qui est en fait la defaultValuepropriété. (Bien que ce cas particulier soit à nouveau confondu par des bogues dans IE <9.)
bobince
4
@BlueRaja: La réponse à cela est encore plus compliquée. :-) Le réglage attr('value', ...)dans jQuery <1.6 définit la propriété, donc la valeur actuelle change et la valeur par défaut ne change pas. En 1.6, il définit l'attribut, donc en théorie la valeur par défaut change et la valeur actuelle ne change pas. Cependant, il existe (plus) d'incohérences dans le navigateur quant à la définition exacte de l' valueattribut. Dans IE, il définit également la valeur actuelle; dans certains navigateurs, il ne définit la valeur actuelle que si la valeur actuelle n'a pas déjà été définie auparavant. [cris]
bobince
1
Tout comme @Quentin l'a dit, "Les attributs sont définis par HTML. Les propriétés sont définies par DOM." La version la plus simple que j'ai lue.
Alan Dong
241

Une propriété est dans le DOM; un attribut est dans le HTML qui est analysé dans le DOM.

Plus de détails

Si vous changez un attribut, le changement sera reflété dans le DOM (parfois avec un nom différent).

Exemple: la modification de l' classattribut d'une balise modifie la classNamepropriété de cette balise dans le DOM. Si vous n'avez aucun attribut sur une balise, vous avez toujours la propriété DOM correspondante avec une valeur vide ou par défaut.

Exemple: alors que votre balise n'a pas d' classattribut, la propriété DOM classNameexiste avec une valeur de chaîne vide.

Éditer

Si vous changez l'un, l'autre sera changé par un contrôleur, et vice versa. Ce contrôleur n'est pas dans jQuery, mais dans le code natif du navigateur.

yunzen
la source
Cela signifie-t-il donc qu'il est préférable de mettre à jour l'attribut parce que vous vous assurez que l'attribut et la propriété sont à la fois mis à jour et alignés?
Luke
1
@Luke le DOM est la représentation technique intérieure, le modèle. Les attributs HTML sont une représentation externe, une vue. Si vous changez l'un, l'autre sera changé par un contrôleur, et vice versa.
yunzen
@HerrSerker Ils sont donc tous deux synchronisés via un contrôleur? Je suppose que c'est juste dans les méthodes attr et prop de jQuery? Voici une modification de votre violon où j'explore davantage - jsfiddle.net/v8wRy - et jusqu'à présent, ils semblent être équivalents.
Luke
3
"Si vous changez l'un, l'autre sera changé par un contrôleur, et vice versa. Ce contrôleur n'est pas dans jQuery, mais dans le code natif des navigateurs." Ce n'est pas vrai pour la plupart des attributs / propriétés. Pour la majorité, ce n'est qu'une traduction à sens unique où un attribut détermine la valeur initiale de la propriété correspondante. Les deux premières réponses expliquent cela en détail.
2015
@Vincent. Je ne vois pas, où les deux premières réponses disent quelque chose de contraire à ma réponse. Bien sûr, la plupart des attributs sont les valeurs initiales des propriétés DOM correspondantes. Mais ils sont mutuellement dépendants. Essayez quelque chose comme jQuery('p').prop('className', 'foo');dans la console Chrome et vous verrez comment l' classattribut thg de chaque paragraphe est 'foo'. Bien sûr, pas dans le code source, qui vient du serveur. C'est une constante.
yunzen
140

C'est juste la distinction entre les attributs HTML et les objets DOM qui crée une confusion. Pour ceux qui sont à l'aise d'agir sur les propriétés natives des éléments DOM tels qu'un this.src this.value this.checkedetc, .propc'est un accueil très chaleureux dans la famille. Pour d'autres, c'est juste une couche supplémentaire de confusion. Clarifions cela.

La façon la plus simple de voir la différence entre .attret .propest l'exemple suivant:

<input blah="hello">
  1. $('input').attr('blah'): retourne 'hello'comme prévu. Pas de surprise ici.
  2. $('input').prop('blah'): renvoie undefined- car il essaie de le faire [HTMLInputElement].blah- et aucune propriété de ce type sur cet objet DOM n'existe. Il n'existe que dans la portée en tant qu'attribut de cet élément, à savoir[HTMLInputElement].getAttribute('blah')

Maintenant, nous changeons quelques choses comme ceci:

$('input').attr('blah', 'apple');
$('input').prop('blah', 'pear');
  1. $('input').attr('blah'): renvoie 'apple'hein? Pourquoi ne pas "poire" car cela a été réglé en dernier sur cet élément. Parce que la propriété a été modifiée sur l'attribut d'entrée, et non sur l'élément d'entrée DOM lui-même - ils fonctionnent pratiquement presque indépendamment les uns des autres.
  2. $('input').prop('blah'): Retour 'pear'

La chose à laquelle vous devez vraiment faire attention est de ne pas mélanger l'utilisation de ceux-ci pour la même propriété dans votre application pour la raison ci-dessus.

Voir un violon démontrant la différence: http://jsfiddle.net/garreh/uLQXc/


.attrvs .prop:

Tour 1: style

<input style="font:arial;"/>
  • .attr('style') - renvoie des styles en ligne pour l'élément correspondant, c'est-à-dire "font:arial;"
  • .prop('style') - retourne un objet de déclaration de style ie CSSStyleDeclaration

Tour 2: valeur

<input value="hello" type="text"/>   

$('input').prop('value', 'i changed the value');
  • .attr('value')- retourne 'hello'*
  • .prop('value') -- Retour 'i changed the value'

* Remarque: jQuery pour cette raison a une .val()méthode, qui en interne est équivalente à.prop('value')

Gary Green
la source
@Neal car il fait mieux référence à la structure des fonctions jquery. "$ ('input'). prop ('blah'): renvoie undefined - car il essaie de faire [HTMLInputElement] .blah - et aucune propriété de ce type sur cet objet DOM n'existe. Elle n'existe que dans la portée en tant qu'attribut de cet élément, c'est-à-dire [HTMLInputElement] .getAttribute ('blah') "
Uğur Gümüşhan
2
Semble différent de la doc, api.jquery.com/prop : "La méthode .prop () doit être utilisée pour définir désactivé et vérifié au lieu de la méthode .attr (). La méthode .val () doit être utilisée pour obtenir et définition de la valeur. "
cygne
53

TL; DR

Utilisez prop()plus attr()dans la majorité des cas.

Une propriété est l'état actuel de l'élément d'entrée. Un attribut est la valeur par défaut.

Une propriété peut contenir des éléments de différents types. Un attribut ne peut contenir que des chaînes

agjmills
la source
1
si possible, venez avec quelques exemples faciles de ce que vous dites et montrez également quand utiliser prop() and when to go for attr(). en attente de réponse :)
Mou
36

Contrôle sale

Ce concept fournit un exemple où la différence est observable: http://www.w3.org/TR/html5/forms.html#concept-input-checked-dirty

Essaye le:

  • cliquez sur le bouton. Les deux cases à cocher ont été cochées.
  • décochez les deux cases.
  • cliquez à nouveau sur le bouton. Seule la propcase à cocher a été cochée. COUP!

$('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>

Pour certains attributs comme disabledon button, l'ajout ou la suppression de l'attribut content disabled="disabled"bascule toujours la propriété (appelée attribut IDL en HTML5) car http://www.w3.org/TR/html5/forms.html#attr-fe-disabled dit:

L'attribut IDL désactivé doit refléter l'attribut de contenu désactivé.

vous pourriez donc vous en tirer, bien qu'il soit moche car il modifie le HTML sans besoin.

Pour d'autres attributs comme checked="checked"on input type="checkbox", les choses se cassent, car une fois que vous cliquez dessus, il devient sale, puis l'ajout ou la suppression de l' checked="checked"attribut content ne fait plus basculer la vérification .

C'est pourquoi vous devriez utiliser principalement .prop, car cela affecte directement la propriété effective, au lieu de compter sur des effets secondaires complexes de modification du code HTML.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Pour être complet, essayez également ces variantes: 1) Avant de cliquer sur le bouton, cochez puis décochez la première case 2) (Pour celle-ci, vous devrez modifier l'extrait de code) Donnez à la première entrée un checkedattribut:checked="checked"
ᴠɪɴᴄᴇɴᴛ
33

Tout est dans le doc :

La différence entre les attributs et les propriétés peut être importante dans des situations spécifiques. Avant jQuery 1.6, la méthode .attr () tenait parfois compte des valeurs de propriété lors de la récupération de certains attributs, ce qui pouvait entraîner un comportement incohérent. Depuis jQuery 1.6, la méthode .prop () fournit un moyen de récupérer explicitement les valeurs des propriétés, tandis que .attr () récupère les attributs.

Alors utilisez un accessoire!

Arnaud F.
la source
2
Donc, cela signifie que lorsque je passe à 1.6, beaucoup de choses vont se casser ??
Naftali aka Neal
Non, c'est juste un comportement incohérent, si ça marche avant, ça marchera toujours avec jQuery 1.6, c'est juste que l'hélice est plus sûre;)
Arnaud F.
6
Je me souviens. $.attr()récupérer des propriétés la plupart du temps, je travaillais avec elle, pas «parfois». La confusion qui en résulte est toujours d'actualité. Malheureusement, j'ai beaucoup de mal à trouver une lecture définitive sur les attributs HTML par rapport aux propriétés DOM, donc je pourrais écrire une réponse ici dans un instant.
3
@ Arnaud-f Pas vrai. Tout le code antérieur à 1.6 qui utilise attr («vérifié») pour cocher les cases sera désormais rompu.
CaptSaltyJack
3
@Matt McDonald: Quel genre de "... difficulté à trouver une lecture définitive sur les attributs HTML par rapport aux propriétés DOM ..." voulez-vous dire? Les propriétés (reflétées ou non) sont décrites dans la spécification HTML DOM2 ; vous devrez peut-être également vous référer aux spécifications DOM2 et DOM3 .
TJ Crowder
28

les attributs sont dans votre document / fichier texte HTML (== imaginez que c'est le résultat de votre balisage html analysé), tandis que les
propriétés sont dans l' arborescence DOM HTML (== essentiellement une propriété réelle d'un objet au sens JS).

Surtout, beaucoup d'entre eux sont synchronisés (si vous mettez à jour la classpropriété, l' classattribut en html sera également mis à jour; et sinon). Mais certains attributs peuvent être synchronisés avec des propriétés inattendues - par exemple, l' attribut checked correspond à la propriété defaultChecked , de sorte que

  • la vérification manuelle d'une case à cocher modifiera la .prop('checked')valeur, mais ne changera pas .attr('checked')et les .prop('defaultChecked')valeurs
  • le paramètre $('#input').prop('defaultChecked', true)changera également .attr('checked'), mais cela ne sera pas visible sur un élément.

La règle générale est la suivante : la .prop()méthode doit être utilisée pour les propriétés / attributs booléens et pour les propriétés qui n'existent pas en html (comme window.location). Tous les autres attributs (ceux que vous pouvez voir dans le html) peuvent et doivent continuer à être manipulés avec la .attr() méthode. ( http://blog.jquery.com/2011/05/10/jquery-1-6-1-rc-1-released/ )

Et voici un tableau qui montre où .prop()est préféré (même s'il .attr()peut encore être utilisé).

table avec utilisation préférée


Pourquoi voudriez-vous parfois utiliser .prop () au lieu de .attr () où ce dernier est officiellement conseillé?

  1. .prop()peut renvoyer n'importe quel type - chaîne, entier, booléen; tandis que .attr()renvoie toujours une chaîne.
  2. .prop()est censé être environ 2,5 fois plus rapide que .attr().
Lakesare
la source
quelque chose a changé, comme ceux - ci: $('#myImageId').prop('src', 'http://example.com/img.png'), var class = $('.myDivClass').prop('class')ou $('#myTextBox').prop('type', 'button'). Et ainsi de suite ...
@ Mr.Wolf, désolé, je ne comprends toujours pas ce que vous voulez dire. Qu'est ce qui a changé'? la syntaxe a toujours été comme ça.
Lakesare
Je pense que le tableau de votre réponse est inutile. Parce que .prop()fonctionne très bien avec toutes les propriétés. Vous ne voulez pas marquer toutes les propriétés dans la .prop()colonne, n'est-ce pas ?
@ Mr.Wolf, je pense que c'est nécessaire, car, comme déjà indiqué, cela «montre où .prop()est préféré (même s'il .attr()peut encore être utilisé)»
Lakesare
J'utilise habituellement .attr()pour définir un événement ce qui .prop()ne peut pas. Comme ceci: $('.myDiv').attr('onclick', 'alert("Hello world!")'). Si vous passez .attr()à .prop(), cela ne fonctionnera pas. Totalement, je pense qu'il n'y a aucune raison d'utiliser .attr()pour définir ou obtenir la valeur de id/class/href/checked/src...... Remarquez que je ne dis pas que vous vous trompez.
20

.attr():

  • Obtenez la valeur d'un attribut pour le premier élément de l'ensemble des éléments correspondants.
  • Vous donne la valeur de l'élément telle qu'elle a été définie dans le html au chargement de la page

.prop():

  • Obtenez la valeur d'une propriété pour le premier élément de l'ensemble des éléments correspondants.
  • Donne les valeurs mises à jour des éléments qui sont modifiées via javascript / jquery
Kgn-web
la source
13

Habituellement, vous souhaiterez utiliser des propriétés. N'utilisez des attributs que pour:

  1. Obtenir un attribut HTML personnalisé (car il n'est pas synchronisé avec une propriété DOM).
  2. Obtenir un attribut HTML qui ne se synchronise pas avec une propriété DOM, par exemple obtenir la "valeur d'origine" d'un attribut HTML standard, comme <input value="abc">.
naor
la source
7

attributes -> HTML

properties -> DOM

NkS
la source
8
Je sais ce que vous voulez dire, mais le HTML est un langage de balisage et le DOM une représentation créée à partir du HTML. Un DOMElement a à la fois des attributs et des propriétés .
t.niese
@ t.niese, attirbuteségalement une propriété deDOM
NkS
La réponse courte est simple.
Nabi KAZ
6

Avant jQuery 1.6, la attr()méthode prenait parfois en compte les valeurs des propriétés lors de la récupération des attributs, ce qui provoquait un comportement plutôt incohérent.

L'introduction de la prop()méthode fournit un moyen de récupérer explicitement les valeurs des propriétés, tout en .attr()récupérant les attributs.

Les documents:

jQuery.attr() Obtenez la valeur d'un attribut pour le premier élément de l'ensemble d'éléments correspondants.

jQuery.prop() Obtenez la valeur d'une propriété pour le premier élément de l'ensemble des éléments correspondants.

Gothburz
la source
3

Rappelez doucement l'utilisation prop(), par exemple:

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

La fonction ci-dessus permet de vérifier si checkbox1 est cochée ou non, si cochée: return 1; sinon: retourne 0. Fonction prop () utilisée ici comme fonction GET.

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

La fonction ci-dessus est utilisée pour définir la case à cocher1 à vérifier et toujours retourner 1. Maintenant, la fonction prop () est utilisée comme fonction SET.

Ne vous trompez pas.

P / S: Lorsque je vérifie la propriété Image src . Si le src est vide, prop renvoie l'URL actuelle de la page (incorrecte) et attr retourne une chaîne vide (droite).

user2657778
la source
Vous avez tort dans cet exemple: <img src="smiley.gif" alt="Smiley face" width="42" height="42" onclick="alert($(this).prop('src'))">. Cela devrait fonctionner et renvoyer l'emplacement de l'image.
2

Une chose .attr()peut faire qui ne .prop()peut pas: affecter les sélecteurs CSS

Voici un problème que je n'ai pas vu dans les autres réponses.

Sélecteur CSS [name=value]

  • répondra à .attr('name', 'value')
  • mais pas toujours .prop('name', 'value')

.prop() affecte seulement quelques sélecteurs d'attributs

.attr() affecte tous les sélecteurs d'attributs

Bob Stein
la source
0

1) Une propriété est dans le DOM; un attribut est dans le HTML qui est analysé dans le DOM.

2) $ (elem) .attr ("vérifié") (1.6.1+) "vérifié" (chaîne) Change avec l'état de la case à cocher

3) $ (elem) .attr ("vérifié") (pré-1.6) true (booléen) Modifié avec l'état de la case à cocher

  • Généralement, nous voulons utiliser un objet DOM plutôt qu'un attribut personnalisé comme data-img, data-xyz.

  • Également une certaine différence lors de l'accès à la checkboxvaleur et href avec attr()et au prop()fur et à mesure que la chose change avec la sortie DOM avec prop()comme lien complet à partir de originet Booleanvaleur pour la case à cocher (pre-1.6)

  • On ne peut accéder aux éléments DOM qu'avec d' propautres alors ça donneundefined

Parth Trivedi
la source
0

Il y a quelques autres considérations dans prop () vs attr ():

  • selectedIndex, tagName, nodeName, nodeType, ownerDocument, defaultChecked et defaultSelected..etc doivent être récupérés et définis avec la méthode .prop (). Ceux-ci n'ont pas d'attributs correspondants et ne sont que des propriétés.

  • Case à cocher pour le type d'entrée

       .attr('checked') //returns  checked
       .prop('checked') //returns  true
       .is(':checked') //returns true
  • La méthode prop renvoie une valeur booléenne pour les éléments cochés, sélectionnés, désactivés, readOnly..etc tandis que attr renvoie la chaîne définie. Ainsi, vous pouvez directement utiliser .prop ('coché') dans if condition.

  • .attr () appelle .prop () en interne, donc la méthode .attr () sera légèrement plus lente que d'y accéder directement via .prop ().

Rishu Ranjan
la source
-2

La réponse de Gary Hole est très pertinente pour résoudre le problème si le code est écrit de cette manière

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

Étant donné que la fonction prop renvoie un CSSStyleDeclarationobjet, le code ci-dessus ne fonctionnera pas correctement dans certains navigateurs (testé avec IE8 with Chrome Frame Plugindans mon cas).

Le changeant ainsi en code suivant

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

résolu le problème.

zawhtut
la source