La plupart des méthodes de requête DOM sont disponibles à la fois sur les Document
et les Eléments
. Par exemple,
console.assert(document.getElementById); console.assert(document.body.getElementById == undefined);
Cependant, getElementById
n'est disponible que sur Document
:
console.assert( document.getElementsByTagName && document.body.getElementsByTagName && document.getElementsByClassName && document.body.getElementsByClassName && document.querySelector && document.body.querySelector && document.querySelectorAll && document.body.querySelectorAll );
Pourquoi en est-il ainsi?
Le standard de vie WHATWG DOM nous dit que :
La compatibilité Web empêche la méthode
getElementById ()
d'être exposée sur des éléments
La recommandation DOM4 du W3C est un peu plus précise :
La méthode
getElementById ()
n'est pas sur les éléments pour des raisons de compatibilité avec les anciennes versions de jQuery. Si un moment vient où cette version de jQuery a disparu, nous pourrons peut-être la prendre en charge.
Cependant, j'ai encore du mal à comprendre quel pourrait être le problème. Comment la présence de ces méthodes pourrait-elle affecter négativement le comportement de jQuery ou d'autres bibliothèques?
J'ai essayé de parcourir d'anciennes versions de jQuery (telles que 1.0.0 et 1.7.0 ) pour voir si l'une de leurs utilisations de getElementById
indique pourquoi cela a pu être un problème. Je vois que getElementById
était autrefois bogué dans certains navigateurs plus anciens, mais ils le détectent et reviennent à une implémentation manuelle fiable à la place. Je ne vois nulle part qu'il pourrait être appelé sur un élément et provoquer un bug. D'où vient ce problème de compatibilité?
3 Réponses :
Comme d'autres l'ont dit dans les commentaires, les identifiants d'élément sont censés être uniques. Il n'y aurait pas besoin d'avoir une méthode getElementById
sur un élément.
D'après l'article de MDN sur getElementById
:
Étant donné que les valeurs d'ID doivent être uniques dans tout le document, il n'est pas nécessaire de disposer de versions "locales" de la fonction.
Il en va de même pour getElementsByName < / code>
Mais getElementsByName n'est disponible que sur le document
, pas sur les éléments. Je crois que l'intention initiale était que les noms soient uniques et utilisés de la même manière que nous utilisons les identifiants maintenant. Cela expliquerait certains des bogues du navigateur que les anciennes versions de jQuery contournaient
Le git blâme
sur https://github.com/w3c/dom La branche principale de a> pointe vers:
Supprimez getElementById de l'élément. https://www.w3.org/Bugs/Public/show_bug.cgi ? id = 23860
et le bogue lié décrit comment jQuery 1.2.5 + 1.2.6 (1.2.x?) sont affectés:
jQuery 1.2.5 suppose que tout nœud trouvé dans le DOM qui a une propriété "getElementById" est un nœud Document. Voir https://bugzilla.mozilla.org/show_bug.cgi?id=933193# c17
Jquery devrait avoir autre chose pour vérifier si l'objet est un nœud Document.
@RaymondPeng: C'est le cas maintenant, mais les sites Web ne sont pas tous mis à jour. Les erreurs durent longtemps lorsque les logiciels populaires les font.
Le fait d'avoir tous vos identifiants uniques vous facilitera vraiment la vie.
Étant donné que les valeurs d'identifiant doivent être uniques dans tout le document, quel en serait l'intérêt?
Je ne peux pas vous donner de réponse définitive, mais je suppose que c'est parce que les attributs
id
devraient être uniques dans le DOM. En tant que tel, peu importe à quel niveau vous effectuez l'appelgetElementById ()
, ils ne l'ont donc implémenté que sur ledocument
.Il ne peut y avoir qu'un seul élément, mais je ne peux m'intéresser à lui que s'il existe dans un sous-arbre particulier du document.
Vous pouvez utiliser
.querySelector ()
pour le déterminer.@Pointy J'ai cité les problèmes de compatibilité des deux spécifications, donc me dire que c'est parce que c'est inutile semble incorrect.
Je ne sais pas comment ou pourquoi une ancienne version de jQuery serait une préoccupation pour le comité des spécifications.
@Pointy: Parce que l'introduction de
Element # getElementById
brise les sites Web existants qui utilisent cette version de jQuery, apparemment largement déployée au moins en 2013.