getAttribute () par rapport aux propriétés des objets Element?


92

Les expressions aiment Element.getAttribute("id")et Element.idrenvoient la même chose.

Lequel faut-il utiliser lorsque nous avons besoin des attributs d'un objet HTMLElement?

Y a-t-il un problème entre les navigateurs avec ces méthodes telles que getAttribute()et setAttribute()?

Ou un impact sur les performances entre l'accès direct aux propriétés des objets et l'utilisation de ces méthodes d'attributs?


Réponses:


126

getAttributerécupère l' attribut d'un élément DOM, tandis que el.idrécupère la propriété de cet élément DOM. Ils ne sont pas les mêmes.

La plupart du temps, les propriétés DOM sont synchronisées avec les attributs.

Cependant, la synchronisation ne garantit pas la même valeur . Un exemple classique est entre el.hrefet el.getAttribute('href')pour un élément d'ancrage.

Par exemple:

<a href="/" id="hey"></a>
<script>
var a = document.getElementById('hey')
a.getAttribute('href') // "/"
a.href // Full URL except for IE that keeps '/'
</script>

Ce comportement se produit car selon le W3C , la propriété href doit être un lien bien formé. La plupart des navigateurs respectent cette norme (devinez qui ne le fait pas?).

Il y a un autre cas pour le inputde » checkedla propriété. La propriété DOM renvoie trueou falsetandis que l'attribut renvoie la chaîne "checked"ou une chaîne vide.

Et puis, certaines propriétés ne sont synchronisées que dans un sens . Le meilleur exemple est la valuepropriété d'un inputélément. Changer sa valeur via la propriété DOM ne changera pas l'attribut (modifier: vérifiez le premier commentaire pour plus de précision).

Pour ces raisons, je vous suggère de continuer à utiliser les propriétés DOM , et non les attributs, car leur comportement diffère d'un navigateur à l'autre.

En réalité, il n'y a que deux cas où vous devez utiliser les attributs:

  1. Un attribut HTML personnalisé, car il n'est pas synchronisé avec une propriété DOM.
  2. Pour accéder à un attribut HTML intégré, qui n'est pas synchronisé à partir de la propriété, et vous êtes sûr d'avoir besoin de l'attribut (par exemple, l'original valued'un inputélément).

Si vous souhaitez une explication plus détaillée, je vous suggère fortement de lire cette page . Cela ne vous prendra que quelques minutes, mais vous serez ravi des informations (que j'ai résumées ici).


9
+1 pour de bons conseils en général. Le problème de la synchronisation est cependant légèrement décalé: la valuepropriété d'une entrée obtient sa valeur initiale de l'attribut mais n'y est pas du tout liée. L' valueattribut est à la place entièrement synchronisé avec la defaultValuepropriété. De même checkedet defaultChecked. Sauf dans l'ancien IE (<= 7 et modes de compatibilité plus tard), qui a cassé getAttribute()et setAttribute().
Tim Down

Ajout de votre commentaire comme "explication supplémentaire" :-)
Florian Margaine

2
Je pense que vous vous trompez dans le premier exemple. a.hrefrenvoie l'URL complète, a.getAttribute("href")retourne l'attribut exactement comme defiend dans la source HTML.
Salman A

Si vous essayez de déterminer si une valeur n'est pas la valeur par défaut, il vaut mieux utiliser des attributs. De nombreux navigateurs modernes renverront une valeur par défaut (par exemple input.formAction) ou une chaîne vide (par exemple a.download), ce qui rend les choses ambiguës. La seule exception concerne les valeurs qui ne sont pas synchronisées dans les deux sens, telles que value.
Kevin Li

Si id n'est pas du tout défini dans le dom, getAttribute retournera null et element.id retournera une chaîne vide. Est-ce une norme?
Maciej Krawczyk

11

getAttribute('attribute') renvoie normalement la valeur de l'attribut sous forme de chaîne, exactement comme défini dans la source HTML de la page.

Cependant, element.attributepourrait renvoyer une valeur normalisée ou calculée de l'attribut. Exemples:

  • <a href="https://stackoverflow.com/foo"></a>
    • a.href contiendra l' URL complète
  • <input type="checkbox" checked>
    • input.checked sera vrai (booléen)
  • <input type="checkbox" checked="bleh">
    • input.checked sera vrai (booléen)
  • <img src='http://dummyimage.com/64x64/000/fff'>
    • img.width sera 0 (nombre) avant le chargement de l'image
    • img.width sera de 64 (nombre) lorsque l'image (ou les premiers octets de celle-ci) est chargée
  • <img src='http://dummyimage.com/64x64/000/fff' width="50%">
    • img.width sera le 50% calculé
  • <img src='http://dummyimage.com/32x32/000/fff' style='width: 50px'>
    • img.width sera 50 (nombre)
  • <div style='background: lime;'></div>
    • div.style sera un objet

3

Selon ce test jsPerf getAttribute est plus lent que la idpropriété.

PS

Curieusement, les deux instructions fonctionnent très mal sur IE8 (par rapport aux autres navigateurs).


3

Utilisez toujours les propriétés sauf si vous avez une raison spécifique de ne pas le faire.

  • getAttribute()et setAttribute()sont cassés dans les anciens IE (et en mode de compatibilité dans les versions ultérieures)
  • les propriétés sont plus pratiques (en particulier celles correspondant aux attributs booléens)

Il y a quelques exceptions :

  • accès aux attributs des <form>éléments
  • accéder aux attributs personnalisés (même si je déconseillerais du tout d'utiliser des attributs personnalisés)

J'ai écrit à ce sujet plusieurs fois sur SO:


Avant IE 8, les propriétés et les attributs étaient traités de la même manière . Comme vous l'avez mentionné précédemment, les propriétés sont la voie à suivre.

@MattMcDonald: Oui, c'est la rupture à laquelle je faisais allusion. Je ne l'ai pas développé dans cette réponse parce que je sentais que je l'avais fait assez dans d'autres réponses auxquelles j'ai lié :)
Tim Down

3

.idenregistre la surcharge de l'appel de fonction. (ce qui est très petit, mais vous avez demandé.)


Salut gdoron, juste par curiosité: j'ai essayé de trouver une explication «officielle» à cela (au-delà du test empirique, ce qui est assez clair;)) mais sans succès. Avez-vous un lien à ce sujet?
mamoo

0

Essayez l'exemple ci-dessous pour comprendre cela complètement. Pour le DIV ci-dessous

<div class="myclass"></div>

Le Element.getAttribute('class')retournera myclassmais vous devez utiliser Element.classNamece qui le récupère dans la propriété DOM.


0

Un domaine où cela fait une grande différence est le style CSS basé sur les attributs.

Considérer ce qui suit:

const divs = document.querySelectorAll('div');

divs[1].custom = true;
divs[2].setAttribute('custom', true);
div {
  border: 1px solid;
  margin-bottom: 8px;
}

div[custom] {
  background: #36a;
  color: #fff;
}
<div>A normal div</div>
<div>A div with a custom property set directly.</div>
<div>A div with a custom attribute set with `setAttribute`</div>

Le div avec la propriété personnalisée définie directement ne reflète pas la valeur de l'attribut et n'est pas sélectionné par notre sélecteur d'attribut (div[custom] ) dans le css.

Le div avec l'attribut personnalisé défini à l'aide setAttribute, cependant, peut être sélectionné à l'aide d'un sélecteur d'attribut css, et stylé en conséquence.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.