447 votes

Les éléments de l'arbre DOM avec des ID deviennent-ils des propriétés globales ?

Je travaille sur une idée pour un simple HTMLElement je suis tombé sur ce qui suit pour Internet Explorer et Chrome :

Pour un HTMLElement avec un id dans l'arborescence DOM, il est possible de récupérer l'élément <div> en utilisant son ID comme nom de variable ou comme propriété de window . Ainsi, pour un <div> comme

<div id="example">some text</div>

sur Internet Explorer 8 et Chrome que tu peux faire :

alert(example.innerHTML); // Alerts "some text".

ou

alert(window["example"].innerHTML); // Alerts "some text".

Alors, est-ce que cela signifie chaque élément de l'arbre DOM est converti en une propriété sur l'objet global ? Et cela signifie-t-il également que l'on peut l'utiliser en remplacement de la fonction getElementById dans ces navigateurs ?

10 votes

3 votes

@Bergi, le commentaire qui indique de ne pas faire cela est maintenant dépassé et même invalide. Par conséquent, je ne trouve pas de raison concrète de ne pas utiliser cette fonctionnalité.

2 votes

@EdmundReed Vous devriez relire la réponse à la question liée - c'est toujours une mauvaise idée : " variables globales implicitement déclarées "ont un support d'outillage faible ou inexistant et " conduire à un code fragile ". N'appelez pas cela une "fonctionnalité", la réponse ci-dessous explique qu'il s'agit simplement d'un bogue qui a été intégré à la norme pour des raisons de compatibilité.

472voto

bobince Points 270740

Ce qui est censé se passer, c'est que les "éléments nommés" sont ajoutés en tant que propriétés apparentes de l'élément d'information. document objet. C'est une très mauvaise idée, car cela permet aux noms d'éléments d'entrer en conflit avec les propriétés réelles des objets de l'UE. document .

IE a aggravé la situation en ajoutant également des éléments nommés en tant que propriétés de la balise window objet. C'est doublement mauvais, car vous devez maintenant éviter de nommer vos éléments d'après un membre de l'un ou l'autre des éléments suivants document ou le window que vous (ou tout autre code de bibliothèque dans votre projet) pourriez vouloir utiliser.

Cela signifie également que ces éléments sont visibles en tant que variables de type global. Heureusement, dans ce cas, toute variable globale réelle var o function dans votre code leur font ombrage, vous n'avez donc pas besoin de vous soucier de la dénomination ici, mais si vous essayez d'effectuer une affectation à une variable globale avec un nom contradictoire et que vous oubliez de la déclarer var vous obtiendrez une erreur dans IE car il tente d'attribuer la valeur à l'élément lui-même.

Il est généralement considéré comme une mauvaise pratique d'omettre var ainsi que de s'appuyer sur le fait que les éléments nommés sont visibles sur le site Web de l'UE. window ou en tant que globales. Tenez-vous en à document.getElementById qui est plus largement soutenue et moins ambiguë. Vous pouvez écrire une fonction wrapper triviale avec un nom plus court si vous n'aimez pas la typographie. Quoi qu'il en soit, il n'y a aucun intérêt à utiliser un cache de recherche id-to-element, car les navigateurs optimisent généralement la fonction getElementById d'utiliser une recherche rapide de toute façon ; tout ce que vous obtenez, ce sont des problèmes lorsque les éléments changent id ou sont ajoutés/supprimés du document.

Opera a copié IE, puis WebKit l'a rejoint, et maintenant, la pratique non standardisée consistant à placer des éléments nommés sur les pages web de l'entreprise est devenue une pratique courante. document et la pratique, jusqu'alors réservée à l'IE, consistant à les mettre sur window son être standardisé par HTML5, dont l'approche consiste à documenter et à normaliser toutes les pratiques terribles que nous infligent les auteurs de navigateurs, afin qu'elles fassent partie intégrante du web pour toujours. Firefox 4 prendra donc également en charge cette fonctionnalité.

Que sont les "éléments nommés" ? Tout ce qui comporte un id et tout ce qui a un name utilisés à des fins d'"identification" : il s'agit de formulaires, d'images, d'ancres et de quelques autres, mais pas d'autres instances sans rapport avec l'objet. name comme les noms des contrôles dans les champs de saisie des formulaires, les noms des paramètres dans les formulaires de demande d'emploi. <param> ou le type de métadonnées dans <meta> . "Identifier name sont celles qui doivent être évitées en faveur de id .

20 votes

Une exception à "l'utilisation de name à éviter" est avec <input> où le name joue un rôle essentiel dans la formation de la clé des paires clé-valeur pour les soumissions de formulaires.

7 votes

Pour info, Firefox ne fait cela que lorsqu'il est en mode bizarrerie.

5 votes

@yahelc : c'est exactement la distinction que je fais. "pas d'autres utilisations de name comme les noms de contrôle dans les champs de saisie des formulaires..."

77voto

TJ VanToll Points 4716

Comme mentionné dans la réponse précédente, ce comportement est connu sous le nom de accès nommé sur l'objet fenêtre . La valeur de la name pour certains éléments et la valeur de l'attribut id pour tous les éléments sont disponibles en tant que propriétés de l'attribut global window objet. Ces éléments sont connus sous le nom d'éléments nommés. Puisque window est l'objet global dans le navigateur, chaque élément nommé sera accessible comme une variable globale.

Cette fonction a été ajoutée à l'origine par Internet Explorer et a finalement été mise en œuvre par tous les autres navigateurs, simplement pour des raisons de compatibilité avec les sites qui dépendent de ce comportement. Il est intéressant de noter que Gecko (le moteur de rendu de Firefox) a choisi d'implémenter cette fonctionnalité dans le navigateur suivant mode bizarrerie uniquement, alors que d'autres moteurs de rendu le laissent actif en mode standard.

Cependant, à partir de Firefox 14, Firefox prend désormais en charge l'accès nommé sur le window en mode standard également. Pourquoi ont-ils changé cela ? Il s'avère qu'il y a encore beaucoup de sites qui dépendent de cette fonctionnalité en mode standard. Microsoft a même a publié une démo marketing qui l'a fait, empêchant la démo de fonctionner dans Firefox.

Webkit a récemment a considéré le contraire en reléguant l'accès nommé sur le window l'objet en mode bizarrerie uniquement. Ils ont décidé de ne pas le faire pour le même raisonnement que Gecko.

Donc aussi fou que cela puisse paraître ce comportement est maintenant techniquement sûr à utiliser dans la dernière version de tous les principaux navigateurs en mode standard. . Mais si l'accès nominatif peut sembler quelque peu pratique, il ne doit pas être utilisé .

Pourquoi ? Une grande partie du raisonnement peut être résumée dans cet article sur les raisons qui ont motivé la décision de la Commission. les variables globales sont mauvaises . En d'autres termes, la présence d'un grand nombre de variables globales supplémentaires entraîne davantage de bogues. Imaginons que vous tapez accidentellement le nom d'une variable de type var et que vous tapez par hasard un id d'un nœud DOM, SURPRISE !

En outre, malgré la normalisation, il existe encore un certain nombre de divergences dans les implémentations de l'accès nommé dans les navigateurs.

  • IE rend incorrectement la valeur de l'élément name accessible pour les éléments de formulaire (input, select, etc).
  • Gecko et Webkit ne font PAS, de manière incorrecte, de <a> accessibles via leur name attribut.
  • Gecko ne traite pas correctement plusieurs éléments nommés portant le même nom (il renvoie une référence à un seul nœud au lieu d'un tableau de références).

Et je suis sûr qu'il y en a d'autres si vous essayez d'utiliser l'accès nommé sur des cas limites.

Comme mentionné dans d'autres réponses, utilisez document.getElementById pour obtenir une référence à un nœud du DOM par son id . Si vous avez besoin d'obtenir une référence à un noeud par son name utilisation des attributs document.querySelectorAll .

S'il vous plaît, ne propagez pas ce problème en utilisant un accès nommé dans votre site. Tant de développeurs web ont perdu du temps à essayer de retrouver ce problème. magique comportement. Nous devons vraiment agir et faire en sorte que les moteurs de rendu désactivent l'accès nommé en mode standard. À court terme, cela mettra fin aux activités de certains sites qui font de mauvaises choses, mais à long terme, cela contribuera à faire avancer le web.

Si cela vous intéresse, j'en parle plus en détail sur mon blog. https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/ .

5 votes

Juste une remarque sur la mise en garde évidente contre la prémisse selon laquelle "il ne faut pas l'utiliser". C'est-à-dire, "il ne devrait pas être utilisé SAUF si vous êtes un cow-boy du code". Les cowboys du code se lancent dans l'aventure.

6 votes

@jeremyfoster à moins que "code cowboy" signifie quelqu'un qui utilise et propage de mauvaises implémentations non conviviales pour les développeurs, je ne suis pas du tout d'accord.

3 votes

La marque d'un bon cow-boy est que beaucoup ne sont pas d'accord. Mais maintenant je suis comme le cow-boy philosophe ou quelque chose comme ça.

23voto

Nick Craver Points 313913

Vous devriez vous en tenir à getElementById() dans ces cas, par exemple :

document.getElementById('example').innerHTML

IE aime mélanger des éléments avec name et ID dans l'espace de noms global, il est donc préférable d'être explicite sur ce que vous essayez d'obtenir.

14voto

Bekim Bacaj Points 2400

La question doit sonner : : "Les balises HTML avec des ID fournis deviennent-elles des éléments DOM globalement accessibles ?"

La réponse est OUI !

C'est ainsi que cela devait fonctionner, et c'est pourquoi les identifiants ont été introduits par le W3C pour commencer.. : L'ID d'une balise HTML dans un environnement de script analysé devient son identifiant d'élément DOM correspondant.

Cependant, Netscape Mozilla a refusé de se conformer au W3C (qui les importunait) et s'est entêté à utiliser l'attribut Name déprécié pour créer des ravages et donc briser la fonctionnalité de script et la commodité de codage apportée par l'introduction des ID uniques par le W3C.

Après le fiasco de Netscape Navigator 4.7, leurs développeurs sont tous allés infiltrer le W3C, tandis que leurs associés supplantaient le Web avec des pratiques erronées et des exemples mal utilisés. Forcer l'utilisation et la réutilisation de l'attribut Name déjà déprécié [!qui n'était pas censé être unique] au même titre que les attributs ID de sorte que les scripts qui utilisaient des poignées ID pour accéder à des éléments DOM particuliers se briseraient tout simplement !

Et ils l'ont fait car ils ont également écrit et publié des leçons et des exemples de codage détaillés [que leur navigateur ne reconnaîtrait pas de toute façon] tels que document.all.ElementID.property au lieu de ElementID.property afin de le rendre au moins inefficace et de donner au navigateur une charge supplémentaire au cas où il ne le casserait pas simplement au niveau du domaine HTML en utilisant le même jeton pour l'attribut Name (maintenant [1996-97], déprécié) et l'attribut ID standard en lui fournissant la même valeur de jeton.

Ils ont facilement réussi à convaincre - à l'époque - l'écrasante armée d'amateurs ignorants de l'écriture de code que les noms et les ID sont pratiquement les mêmes, sauf que l'attribut ID est plus court et donc plus économe en octets et plus pratique pour le codeur que l'ancienne propriété Name. Ce qui était bien sûr un mensonge. Ou - dans leurs articles publiés sur le HTML, convaincant que vous devrez fournir à la fois Name et ID à vos balises pour qu'elles soient accessibles par le moteur de script.

Les tueurs de Mosaic [nom de code "Mozilla"] étaient si furieux qu'ils se sont dit "si nous tombons, Internet doit tomber aussi".

Les Microsoft montants - d'autre part - étaient si naïfs qu'ils pensaient qu'ils devaient conserver la propriété Name, dépréciée et marquée pour la suppression, et la traiter comme s'il s'agissait d'un ID, c'est-à-dire un identifiant unique, afin de ne pas casser la fonctionnalité de script des vieilles pages codées par les stagiaires de Netscape. Ils se trompaient lourdement...

Et le retour d'une collection de tableaux d'éléments contradictoires n'était pas non plus une solution à ce problème délibérément créé par l'homme. En fait, cela va à l'encontre du but recherché.

Et c'est la seule raison pour laquelle le W3C s'est enlaidi et nous a donné des idioties telles que document.getElementById et la syntaxe rococo du genre qui l'accompagne... (...)

5voto

qff Points 185

Oui, ils le font.

Testé dans Chrome 55, Firefox 50, IE 11, IE Edge 14 et Safari 10.
avec l'exemple suivant :

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="im_not_particularly_happy_with_that">
    Hello World!
  </div>
  <script>
    im_not_particularly_happy_with_that.innerText = 'Hello Internet!';
  </script>
  <!-- Looking at you W3 HTML5 spec group ಠ_ಠ -->
</body>
</html>

http://jsbin.com/mahobinopa/edit?html,output

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X