Quelle est la différence entre les propriétés et les attributs en HTML?

409

Après les modifications apportées dans jQuery 1.6.1, j'ai essayé de définir la différence entre les propriétés et les attributs en HTML.

En regardant la liste des notes de publication de jQuery 1.6.1 (près du bas), il semble que l'on puisse classer les propriétés et attributs HTML comme suit:

  • Propriétés: tout ce qui a une valeur booléenne ou qui est calculé par UA tel que selectedIndex.

  • Attributs: «Attributs» qui peuvent être ajoutés à un élément HTML qui n'est ni booléen ni contenant une valeur générée par UA.

Pensées?

schalkneethling
la source
6
Copie
Naftali aka Neal

Réponses:

827

Lors de l'écriture de code source HTML, vous pouvez définir des attributs sur vos éléments HTML. Ensuite, une fois que le navigateur a analysé votre code, un nœud DOM correspondant sera créé. Ce nœud est un objet et a donc des propriétés .

Par exemple, cet élément HTML:

<input type="text" value="Name:">

a 2 attributs ( typeet value).

Une fois que le navigateur a analysé ce code, un objet HTMLInputElement sera créé et cet objet contiendra des dizaines de propriétés telles que: accept, accessKey, align, alt, attributs, autofocus, baseURI, vérifié, childElementCount, childNodes, children, classList, className, clientHeight, etc.

Pour un objet de noeud DOM donné, les propriétés sont les propriétés de cet objet et les attributs sont les éléments de la attributespropriété de cet objet.

Lorsqu'un nœud DOM est créé pour un élément HTML donné, bon nombre de ses propriétés se rapportent à des attributs portant des noms identiques ou similaires, mais ce n'est pas une relation un à un. Par exemple, pour cet élément HTML:

<input id="the-input" type="text" value="Name:">

le noeud DOM correspondant aura id, typeet les valuepropriétés (entre autres):

  • La idpropriété est une propriété reflétée pour l' idattribut: obtenir la propriété lit la valeur d'attribut et définir la propriété écrit la valeur d'attribut. idest une propriété reflétée pure , elle ne modifie ni ne limite la valeur.

  • La typepropriété est une propriété reflétée pour l' typeattribut: obtenir la propriété lit la valeur d'attribut et définir la propriété écrit la valeur d'attribut. typen'est pas une propriété reflétée pure car elle est limitée aux valeurs connues (par exemple, les types valides d'une entrée). Si vous l'aviez <input type="foo">, alors theInput.getAttribute("type")vous donne "foo"mais theInput.typevous donne "text".

  • En revanche, la valuepropriété ne reflète pas l' valueattribut. Il s'agit plutôt de la valeur actuelle de l'entrée. Lorsque l'utilisateur modifie manuellement la valeur de la zone de saisie, la valuepropriété reflétera cette modification. Donc, si l'utilisateur entre "John"dans la zone de saisie, alors:

    theInput.value // returns "John"

    tandis que:

    theInput.getAttribute('value') // returns "Name:"

    La valuepropriété reflète le contenu textuel actuel à l'intérieur de la zone de saisie, tandis que l' valueattribut contient le contenu textuel initial de l' valueattribut du code source HTML.

    Donc, si vous voulez savoir ce qui se trouve actuellement dans la zone de texte, lisez la propriété. Si vous voulez cependant savoir quelle était la valeur initiale de la zone de texte, lisez l'attribut. Ou vous pouvez utiliser la defaultValuepropriété, qui est un pur reflet de l' valueattribut:

    theInput.value                 // returns "John"
    theInput.getAttribute('value') // returns "Name:"
    theInput.defaultValue          // returns "Name:"

Il y a plusieurs propriétés qui reflètent directement leur attribut ( rel, id), certains sont des réflexions directes avec des noms légèrement différents ( htmlForreflète l' forattribut, classNamereflète l' classattribut), beaucoup qui reflètent leur attribut , mais avec restrictions / modifications ( src, href, disabled, multiple), etc. sur. La spécification couvre les différents types de réflexion.

Šime Vidas
la source
1
Hey Sime, je suppose que c'est assez ambigu, surtout si vous regardez ici: w3.org/TR/html4/index/attributes.html , et il n'y a pas de réponse claire. Il faut essentiellement suivre ce qui est indiqué dans le résumé sur le blog jQuery et même alors, l'un sera mappé à l'autre et fonctionnera dans les deux cas avec un léger
impact sur les
4
@oss Votre lien fait référence à une liste d'attributs HTML. Cette liste n'est pas ambiguë - ce sont des attributs.
Šime Vidas
y a-t-il des documents sur la relation? @ ŠimeVidas
SKing7
3
Où pourrais-je trouver une liste complète d'attributs aux propriétés (comme for-> htmlFor) et de même une liste de propriétés qui prennent leur valeur initiale d'un attribut, mais ne la reflètent pas ( input.value). Je m'attends à ce que ce soit quelque part dans la source d'une bibliothèque comme github.com/Matt-Esch/virtual-dom mais ce n'est pas vraiment documenté.
sstur
1
@Pim Je ne l'ai pas lu moi-même, mais cette série d'articles en 4 parties semble être une excellente ressource: twitter.com/addyosmani/status/1082177515618295808
Šime Vidas
53

Après avoir lu la réponse de Sime Vidas , j'ai cherché plus et trouvé une explication très simple et facile à comprendre dans les documents angulaires .

Attribut HTML et propriété DOM


Les attributs sont définis par HTML. Les propriétés sont définies par le DOM (Document Object Model).

  • Quelques attributs HTML ont un mappage 1: 1 avec les propriétés. iden est un exemple.

  • Certains attributs HTML n'ont pas de propriétés correspondantes. colspanen est un exemple.

  • Certaines propriétés DOM n'ont pas d'attributs correspondants. textContent en est un exemple.

  • De nombreux attributs HTML semblent correspondre aux propriétés ... mais pas de la façon dont vous pourriez le penser!

Cette dernière catégorie prête à confusion jusqu'à ce que vous compreniez cette règle générale:

Les attributs initialisent les propriétés DOM, puis ils sont effectués. Les valeurs des propriétés peuvent changer; les valeurs d'attribut ne peuvent pas.

Par exemple, lorsque le navigateur s'affiche <input type="text" value="Bob">, il crée un nœud DOM correspondant avec une valuepropriété initialisée à "Bob".

Lorsque l'utilisateur entre "Sally" dans la zone de saisie, la value propriété de l' élément DOM devient "Sally". Mais l' value attribut HTML reste inchangé à mesure que vous découvrez si vous demandez à l'élément d'entrée sur cet attribut: input.getAttribute('value')renvoie "Bob".

L'attribut HTML valuespécifie la valeur initiale ; la value propriété DOM est la valeur actuelle .


L' disabledattribut est un autre exemple particulier. La disabledpropriété d' un bouton est falsepar défaut, donc le bouton est activé. Lorsque vous ajoutez l' disabledattribut, sa seule présence initialise la disabledpropriété du bouton pour trueque le bouton soit désactivé.

L'ajout et la suppression de l' disabledattribut désactive et active le bouton. La valeur de l'attribut n'est pas pertinente, c'est pourquoi vous ne pouvez pas activer un bouton en écrivant<button disabled="false">Still Disabled</button>.

La définition de la disabled propriété du bouton désactive ou active le bouton. La valeur de la propriété compte.

L'attribut HTML et la propriété DOM ne sont pas la même chose, même s'ils ont le même nom.

subtleseeker
la source
Cet exemple n'est pas correct: l' colspanattribut a la colSpanpropriété. ... Alors, quel attribut n'a pas de propriété associée maintenant?
Robert Siemer
46

Les réponses expliquent déjà comment les attributs et les propriétés sont traités différemment, mais je voudrais vraiment souligner à quel point c'est complètement fou . Même si c'est dans une certaine mesure la spécification.

Il est fou d'avoir certains attributs (par exemple id, class, foo, bar ) pour ne conserver qu'un seul type de valeur dans le DOM, tandis que certains attributs (par exemple coché, sélectionné ) pour conserver deux valeurs; c'est-à-dire la valeur "quand il a été chargé" et la valeur de "l'état dynamique". (Le DOM n'est-il pas censé représenter l'état du document dans sa totalité?)

Il est absolument essentiel que deux champs de saisie , par exemple un texte et une case à cocher, se comportent de la même manière . Si le champ de saisie de texte ne conserve pas une valeur distincte "quand il a été chargé" et la valeur "actuelle, dynamique", pourquoi la case à cocher? Si la case à cocher a deux valeurs pour l' attribut vérifié , pourquoi n'en a-t-il pas deux pour ses attributs class et id ? Si vous vous attendez à changer la valeur d'un champ de saisie de texte * et que vous vous attendez à ce que le DOM (c'est-à-dire la "représentation sérialisée") change, et reflète ce changement, pourquoi diable ne vous attendriez-vous pas à la même chose à partir d'un champ de saisie de case à cocher type sur l'attribut vérifié?

La différenciation de "c'est un attribut booléen" n'a tout simplement aucun sens pour moi, ou n'est tout au moins pas une raison suffisante pour cela.

sibidiba
la source
21
Ce n'est pas une réponse mais je suis d'accord avec vous; c'est totalement fou.
Samuel
Oui, ce concept est nul et ne devrait pas être tellement standardisé. C'était l'un des cas (comme innerHTML par exemple) qui était bon dans l'ancien IE et aurait dû être adopté par les normes. Les propriétés et les attributs ont été synchronisés dans la mesure du possible, même les attributs personnalisés, ce qui rend la syntaxe js dot très lisible. HTML5 fait des balises HTML personnalisées des citoyens de première classe, les attributs personnalisés devraient également l'être. Cette fonctionnalité étant supprimée car l'ancien IE est toujours un vrai problème - nous ne voyons que beaucoup de sociétés traditionnellement bloquées avec IE pour les anciens systèmes qui les trouvent maintenant cassées dans IE10.
mike nelson
48
Ce n'est pas fou. Vous avez mal compris. L' checkedattribut est représenté par la defaultCheckedpropriété (de même pour une entrée de texte, l' valueattribut est représenté par la defaultValuepropriété). Une deuxième propriété checked,, est requise pour indiquer si la case à cocher est cochée car elle fait partie intrinsèque de la fonctionnalité d'une case à cocher: elle est interactive et peut être modifiée (et réinitialisée à la valeur par défaut, si un bouton de réinitialisation de formulaire est présent) par l'utilisateur , d'une manière qui idn'est pas un autre attribut tel que n'est pas. Cela n'a rien à voir avec le fait qu'il s'agit d'un attribut booléen.
Tim Down
3
@TimDown - Merci. Cela m'a vraiment permis de surmonter la WTF? bosse.
pedz
12
@TimDown Je pense toujours que c'est "fou" parce que toute approche logique ferait correspondre le nom de la propriété et le nom de l'attribut, ou du moins n'aurait pas un nom d'attribut et une correspondance de nom de propriété qui ne sont pas liés (c'est-à-dire que l'attribut vérifié se réfère à defaultChecked alors que la propriété vérifiée n'est pas liée). En fait, l'approche logique que tout le monde suppose que c'est le cas au départ serait de ne pas du tout séparer les attributs et les propriétés. Les attributs ne doivent pas être immuables, mais doivent toujours refléter les valeurs des propriétés. Il ne devrait pas y avoir de distinction entre les deux.
dallin
10

bien ceux-ci sont spécifiés par le w3c ce qui est un attribut et ce qui est une propriété http://www.w3.org/TR/SVGTiny12/attributeTable.html

mais actuellement attr et prop ne sont pas si différents et il y a presque le même

mais ils préfèrent les accessoires pour certaines choses

Résumé de l'utilisation préférée

La méthode .prop () 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 méthode .attr ().

Eh bien, en fait, vous n'avez pas à changer quelque chose si vous utilisez attr ou prop ou les deux, les deux fonctionnent mais j'ai vu dans ma propre application que prop fonctionnait là où atrr ne fonctionnait pas, alors j'ai pris mon prop 1.6 app =)

Daniel Ruf
la source
Salut Daniel, je l'ai lu. Il semble juste qu'il existe une définition claire pour séparer les deux, car certains des éléments mentionnés par Sime ci-dessous peuvent également être ajoutés à l'élément HTML, par exemple alt. Continuera à lire certaines des spécifications HTML et verra s'il existe effectivement un moyen de distinguer clairement les deux dans la pratique.
schalkneethling
3
Ce document concerne SVG et non HTML.
Luzado
5

Propriétés et attributs HTML de différence:

Examinons d'abord les définitions de ces mots avant d'évaluer la différence en HTML:

Définition anglaise:

  • Les attributs font référence à des informations supplémentaires sur un objet.
  • Les propriétés décrivent les caractéristiques d'un objet.

Dans le contexte HTML:

Lorsque le navigateur analyse le HTML, il crée une structure de données arborescente qui est fondamentalement une représentation en mémoire du HTML. Si la structure de données de l'arborescence contient des nœuds qui sont des éléments HTML et du texte. Les attributs et les propriétés s'y rapportent de la manière suivante:

  • Les attributs sont des informations supplémentaires que nous pouvons mettre dans le HTML pour initialiser certaines propriétés DOM.
  • Les propriétés sont formées lorsque le navigateur analyse le code HTML et génère le DOM. Chacun des éléments du DOM possède son propre ensemble de propriétés qui sont toutes définies par le navigateur. Certaines de ces propriétés peuvent avoir leur valeur initiale définie par des attributs HTML. Chaque fois qu'une propriété DOM change et a une influence sur la page rendue, la page sera immédiatement restituée

Il est également important de réaliser que le mappage de ces propriétés n'est pas de 1 à 1. En d'autres termes, tous les attributs que nous donnons sur un élément HTML n'auront pas une propriété DOM nommée similaire.

En outre, différents éléments DOM ont des propriétés différentes. Par exemple, un <input>élément a une propriété value qui n'est pas présente sur une <div>propriété.

Exemple:

Prenons le document HTML suivant:

 <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">  <!-- charset is a attribute -->
  <meta name="viewport" content="width=device-width"> <!-- name and content are attributes -->
  <title>JS Bin</title>
</head>
<body>
<div id="foo" class="bar foobar">hi</div> <!-- id and class are attributes -->
</body>
</html>

Ensuite, nous inspectons le <div>, dans la console JS:

 console.dir(document.getElementById('foo'));

Nous voyons les propriétés DOM suivantes (chrome devtools, pas toutes les propriétés affichées):

propriétés et attributs html

  • Nous pouvons voir que l'identifiant d'attribut dans le HTML est désormais également une propriété id dans le DOM. L'identifiant a été initialisé par le HTML (bien que nous puissions le changer avec javascript).
  • Nous pouvons voir que l'attribut class dans le HTML n'a pas de propriété de classe correspondante ( classest un mot clé réservé dans JS). Mais en fait 2 propriétés, classListet className.
Willem van der Veen
la source