Question .prop () vs .attr ()


Alors 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 faire doit passer à l'aide de prop(), tout le vieux attr() les appels vont casser si je passe à la version 1.6?

METTRE À 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 le getAttribute comme une chaîne, et le attr comme une chaîne, mais le prop comme un CSSStyleDeclaration, Pourquoi? Et comment cela affecte-t-il mon codage dans le futur?


2053
2018-05-03 19:33


origine


Réponses:


Mise à jour le 1er 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 de sites Web qui avait été prévue, l'équipe jQuery retourné attr() à quelque chose de proche (mais pas exactement le même que) son ancien comportement pour les attributs booléens. John Resig aussi blogué à ce sujet. Je peux voir la difficulté qu'ils étaient, mais toujours en désaccord avec la recommandation de préférer attr().

Réponse originale

Si vous avez seulement utilisé jQuery et pas directement le DOM, cela pourrait être un changement confus, bien que ce soit une amélioration conceptuelle. Pas si bon pour les bazillions de sites utilisant jQuery qui se cassera à 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 quoi attr() l'habitude de faire. Remplacer les appels vers attr() avec prop() dans votre code fonctionnera généralement.
  • Les propriétés sont généralement plus simples à gérer que les attributs. Une valeur d'attribut peut seulement être une chaîne alors qu'une propriété peut être de n'importe quel type. Par exemple, le checked la propriété est un booléen, le style propriété est un objet avec des propriétés individuelles pour chaque style, le size la propriété est un nombre.
  • Lorsqu'une propriété et un attribut du même nom existent, la mise à jour de l'un mettra à jour l'autre, mais ce n'est pas le cas pour certains attributs d'entrées, tels que value et checked: pour ces attributs, la propriété représente toujours l'état actuel alors que l'attribut (sauf dans les anciennes versions de IE) correspond à la valeur / vérification par défaut de l'entrée (reflétée dans le defaultValue / defaultChecked propriété).
  • Cette modification supprime une partie de la couche de magie jQuery bloquée devant les attributs et les propriétés, ce qui signifie que les développeurs de jQuery devront 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 déconcertée par les propriétés et les attributs, vous devez prendre du recul et en apprendre un peu plus à ce sujet, puisque jQuery n'essaye plus autant de vous protéger de ce genre de choses. Pour le mot autoritaire mais un peu sec sur le sujet, il y a les spécifications: DOM4, DOM HTML, 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, de sorte que vous pouvez trouver leur Référence DOM utile. Il y a un section sur les propriétés des éléments.

Comme un exemple de la façon dont les propriétés sont plus simples à traiter que les attributs, considérez une case à cocher qui est initialement vérifiée. Voici deux parties possibles du code HTML valide pour ce faire:

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

Alors, comment savoir si la case à cocher 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 le checked Propriété booléenne, qui a existé et a fonctionné parfaitement dans tous les principaux navigateurs scriptables depuis 1995:

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

La propriété permet également de cocher ou de décocher la case à cocher trivial:

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

En jQuery 1.6, cela devient sans ambiguïté

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

L'idée d'utiliser le checked attribut pour script une case à cocher est inutile et inutile. La propriété est ce dont vous avez besoin.

  • Il n'est pas évident de savoir quelle est la bonne façon de cocher ou de décocher la case checked attribut
  • 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 dit rien sur le fait que la case à cocher de la page soit cochée. Voir http://jsfiddle.net/VktA6/49/.

1734
2018-05-03 23:06



je pense 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 OOP, il a 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). Certains éléments de l'élément Propriétés obtenir leur initiale valeurs de les attributs avec des noms identiques ou similaires (value obtient sa valeur initiale à partir de l'attribut "value"; href obtient sa valeur initiale à partir de l'attribut "href", mais ce n'est pas exactement la même valeur; className de l'attribut "class"). D'autres propriétés obtiennent leurs valeurs initiales d'une autre manière: par exemple, le parentNode la propriété obtient sa valeur en fonction de ce que son élément parent est; un élément a toujours un style propriété, qu'elle possède 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 omettant beaucoup de choses):

+ ------------------------------------------- +
| HTMLAnchorElement |
+ ------------------------------------------- +
| href: "http://example.com/foo.html" |
| nom: "fooAnchor" |
| id: "fooAnchor" |
| className: "test un" |
| attributs: |
| href: "foo.html" |
| nom: "fooAnchor" |
| id: "fooAnchor" |
| class: "tester un" |
+ ------------------------------------------- +

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 la base, un certain nombre de propriétés réécrit l'attribut dont ils dérivent si vous les définissez. Mais pas tous, et comme vous pouvez le voir hrefci-dessus, le mapping n'est pas toujours un "pass the value on", parfois il y a de l'interprétation.

Quand je parle de propriétés étant les propriétés d'un objet, je ne parle pas dans l'abstrait. Voici un 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 y a quelques variations.)

le link objet est une chose réelle, et vous pouvez voir il y a une réelle distinction entre l'accès à un propriété dessus, et accéder à un attribut.

Comme Tim l'a dit, le grande majorité de l'époque, nous voulons travailler avec des propriétés. En partie parce que leurs valeurs (même leurs noms) ont tendance à être plus cohérentes entre les navigateurs. Nous souhaitons surtout travailler avec des attributs quand il n'y a pas de propriété liée (attributs personnalisés), ou quand nous savons que pour cet attribut particulier, l'attribut et la propriété ne sont pas 1: 1 (comme avec href et "href" ci-dessus).

Les propriétés standard sont définies 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 incluraient, par exemple, data-xyz attributs que vous pourriez mettre sur les éléments pour fournir des métadonnées à votre code (maintenant que cela est valide à partir de HTML5, tant que vous respectez le data- préfixe). (Les versions récentes de jQuery vous donnent accès à data-xyz éléments via le data fonction, mais cette fonction est ne pas juste un accesseur pour data-xyz attributs [il fait à la fois plus et moins que cela]; sauf si vous avez réellement besoin de ses fonctionnalités, j'utiliserais le attr fonction d'interagir avec data-xyz attribut.)

le attr fonction utilisée pour avoir une logique alambiquée autour d'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 prop et attr était destiné à les désamorcer. Brièvement dans v1.6.0 jQuery est allé trop loin à cet égard, mais la fonctionnalité a été rapidement ajouté à attr gérer les situations courantes où les gens utilisent attr quand techniquement ils devraient utiliser prop.


621
2018-05-04 14:27



Ce changement a été long à venir pour jQuery. Pendant des années, ils se sont contentés d'une fonction nommée attr() ce sont principalement les propriétés DOM qui sont récupérées, 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() récupère la propriété DOM spécifiée, $.fn.attr() récupère l'attribut HTML spécifié.

Pour bien comprendre leur fonctionnement, 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 associées pour les événements, le rendu et à d'autres fins.

Visualisation: HTML AttributesL'attribut de classe est montré 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 du navigateur au navigateur. Cependant, ils peuvent être vitaux 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 de l'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éments. Ces propriétés sont similaires aux attributs, mais ne sont accessibles que par JavaScript. C'est une différence importante qui aide à 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: DOM Properties

Ici, vous remarquerez une liste de propriétés sous l'onglet "DOM" dans Firebug. Ce sont des propriétés DOM. Vous remarquerez tout de suite un certain nombre d'entre eux, car vous les aurez 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 sur le nouveau code pour l'une ou l'autre des fonctions, je peux affirmer avec confiance que la confusion est plus liée à la différence entre les attributs HTML et les propriétés du DOM qu'avec le code lui-même. J'espère que cela vous a éclairci certaines choses.

-Mat


234
2018-05-03 20:05



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

Détails supplémentaires

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

Exemple: Changer le class attribut d'une étiquette va changer la className propriété de cette balise dans le DOM. Si vous n'avez aucun attribut sur une étiquette, vous avez toujours la propriété DOM correspondante avec une valeur vide ou une valeur par défaut.

Exemple: Alors que votre tag n'a pas class attribut, la propriété DOM className existe avec une valeur de chaîne vide.

modifier

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.


232
2017-09-27 16:55



C'est juste la distinction entre les attributs HTML et les objets DOM qui provoque une confusion. Pour ceux qui sont à l'aise d'agir sur les éléments DOM des propriétés natives telles this.src  this.value  this.checked etc, .prop est un accueil très chaleureux à la famille. Pour les autres, c'est juste une couche supplémentaire de confusion. Voyons cela clair.

Le moyen le plus simple de voir la différence entre .attr et .prop est l'exemple suivant:

<input blah="hello">
  1. $('input').attr('blah'): résultats 'hello'comme prévu. Pas de surprises ici.
  2. $('input').prop('blah'): résultats undefined - Parce qu'il essaie de faire [HTMLInputElement].blah - et aucune propriété de cet objet DOM n'existe. Il n'existe que dans la portée en tant qu'attribut de cet élément, c'est-à-dire [HTMLInputElement].getAttribute('blah')

Maintenant nous changeons quelques choses comme ça:

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

La chose que vous devez vraiment faire attention est juste ne mélangez pas l'utilisation de ceux-ci pour la même propriété tout au long de votre application pour la raison ci-dessus.

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


.attr contre .prop:

Round 1: style

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

Round 2: valeur

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

$('input').prop('value', 'i changed the value');
  • .attr('value') -- résultats 'hello' *
  • .prop('value') -- résultats 'i changed the value'

* Note: jQuery pour cette raison a un .val() méthode, qui est interne à l'équivalent de .prop('value')


131
2018-05-19 10:18



TL; DR

Utilisation prop() plus de 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 choses de types différents. Un attribut ne peut contenir que des chaînes


48
2017-07-16 09:45



Vérification sale

Ce concept est 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é vérifiées.
  • décochez les deux cases.
  • cliquez à nouveau sur le bouton. Seulement le prop checkbox 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 disabled sur button, en ajoutant ou en supprimant l'attribut de contenu disabled="disabled" bascule toujours la propriété (appelée attribut IDL en HTML5) parce que 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é.

donc vous pourriez vous en tirer, même si c'est moche car il modifie HTML sans besoin.

Pour d'autres attributs comme checked="checked" sur input type="checkbox", les choses se cassent, parce qu'une fois que vous cliquez dessus, il devient sale, puis en ajoutant ou en supprimant le checked="checked" attribut de contenu ne bascule plus la vérification.

C'est pourquoi vous devriez utiliser surtout .prop, car il affecte directement la propriété effective, au lieu de s'appuyer sur des effets secondaires complexes.


34
2017-07-06 11:43



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 () prenait parfois en compte des valeurs de propriété lors de la récupération de certains attributs, ce qui pouvait entraîner un comportement incohérent. À partir de jQuery 1.6, la méthode .prop () fournit un moyen de récupérer explicitement les valeurs de propriété, tandis que .attr () récupère uniquement les attributs.

Alors utilisez le prop!


32
2018-05-03 19:35