162 votes

Meilleure pratique : Accéder aux éléments de formulaire par l'attribut HTML id ou name ?

Comme tout développeur JavaScript expérimenté le sait, il existe de nombreuses (trop nombreuses) façons de faire la même chose. Par exemple, disons que vous avez un champ de texte comme suit :

<form name="myForm">  
    <input type="text" name="foo" id="foo" />

Il existe plusieurs façons d'y accéder en JavaScript :

[1]  document.forms[0].elements[0];
[2]  document.myForm.foo;
[3]  document.getElementById('foo');
[4]  document.getElementById('myForm').foo;
     ... and so on ...

Les méthodes [1] et [3] sont bien documentées dans la documentation de Mozilla Gecko, mais aucune n'est idéale. La méthode [1] est tout simplement trop générale pour être utile et la méthode [3] requiert à la fois un identifiant et un nom (en supposant que vous envoyez les données à un langage côté serveur). Idéalement, il est préférable de n'avoir qu'un attribut id ou un attribut name (avoir les deux est plus compliqué). quelque peu redondant, surtout si l'id n'est nécessaire pour aucun css, et augmente la probabilité de fautes de frappe, etc).

[Mais je ne l'ai pas vu référencé dans la documentation de Gecko et je m'inquiète à la fois de la compatibilité ascendante et de la compatibilité entre navigateurs (et bien sûr, je veux être aussi conforme aux normes que possible).

Quelle est la meilleure pratique en la matière ? Quelqu'un peut-il indiquer quelque chose dans la documentation DOM ou dans les spécifications du W3C qui pourrait résoudre ce problème ?

Notez que je suis spécifiquement intéressé par une solution sans bibliothèque (jQuery/Prototype).

0 votes

Je suppose que je cherche le moyen le plus conforme aux normes d'accéder à un élément de formulaire en utilisant l'attribut name...

5 votes

"Avoir les deux est quelque peu redondant, surtout si l'identifiant n'est pas nécessaire pour les CSS, et augmente la probabilité de fautes de frappe" -- L'identifiant est nécessaire pour une utilisation efficace des étiquettes. Pas seulement pour les CSS.

1 votes

Il arrive qu'il y ait plusieurs formulaires sur une page Web et que les attributs d'identification entrent en collision.

116voto

Doin Points 540

Donnez à votre formulaire un id seulement, et votre entrée a nom seulement :

<form id="myform">
  <input type="text" name="foo">

La façon la plus conforme aux normes et la moins problématique d'accéder à votre élément d'entrée est donc via :

document.getElementById("myform").elements["foo"]

en utilisant .elements["foo"] au lieu de simplement .foo est préférable car ce dernier pourrait retourner une propriété de la forme nommée "foo" plutôt qu'un élément HTML !

0 votes

Je ne savais pas qu'il y avait autant d'options ! Mais je préfère cette réponse, combinée à l'utilisation de validateForm(this) pour transmettre l'objet du formulaire.

0 votes

Pourquoi cette option est-elle préférée à onsubmit="myFunc(this) ; return false ;"?

1 votes

@Karl... Qu'est-ce que vous essayez d'obtenir ? Outre le fait que l'intégration de JS dans votre HTML est plutôt inélégante (et souvent inefficace, puisqu'elle crée une fonction d'encapsulation autour du code), le fait que vous ne soyez pas en mesure d'intégrer des JS dans votre code HTML est une erreur. toujours retourner false signifie que votre formulaire sera jamais soumettre. Donc, à moins que le formulaire ne soit pas censé être soumis (peut-être est-il entièrement utilisé par du code JS), ou à moins que myFunc(this) ne le soumette via AJAX (et que vous ne vous souciiez pas de faire un submit normal en cas d'échec d'AJAX), ...alors vous avez fait une erreur.

38voto

Justin Johnson Points 16243

[1] document.forms[0].elements[0] ;

" Non-omg-jamais ! Le mot " " me vient à l'esprit lorsque je vois cette méthode d'accès aux éléments. Le problème avec cette méthode est qu'elle suppose que le DOM est une structure de données normale (par exemple, un tableau) dans laquelle l'ordre des éléments est statique, cohérent ou fiable. Nous savons que 99,9999% du temps, ce n'est pas le cas. Réordonner ou input dans le formulaire, en ajoutant un autre form à la page précédant le formulaire en question, ou le déplacement du formulaire en question sont autant de cas où ce code est cassé. En bref : ce code est très fragile. Dès que vous ajoutez ou déplacez quelque chose, il va se casser.

[2] document.myForm.foo ;

Je suis avec Sergey ILinsky sur ce sujet :

  • Accéder à des éléments arbitraires en se référant à leur id attribut : document.getElementById("myform");
  • Accéder aux éléments de formulaire nommés par leur nom, par rapport à leur élément de formulaire parent : document.getElementById("myform").foo;

Mon principal problème avec cette méthode est que le name est inutile lorsqu'il est appliqué à un formulaire. Le nom n'est pas transmis au serveur dans le cadre du POST/GET et ne fonctionne pas pour les signets de type hachage.

[3] document.getElementById('foo') ;

À mon avis, c'est la méthode la plus préférable. L'accès direct est la méthode la plus concise et la plus claire.

[4] document.getElementById('myForm').foo ;

À mon avis, cette méthode est acceptable, mais plus verbeuse que nécessaire. La méthode n°3 est préférable.


Il se trouve que je regardais un vidéo de Douglas Crockford et il s'est exprimé sur ce sujet. Le point d'intérêt est à -12:00. Pour résumer :

  • Les collections de documents (document.anchor, document.form, etc.) sont obsolètes et non pertinentes (méthode 1).
  • El name est utilisé pour nommer les choses, pas pour y accéder. Il sert à nommer des éléments tels que les fenêtres, les champs de saisie et les balises d'ancrage.
  • "L'ID est la chose que vous devez utiliser pour identifier de manière unique un élément afin de pouvoir y accéder. Ils (nom et ID) étaient autrefois interchangeables, mais ils ne le sont plus."

Alors voilà. Sémantiquement, c'est ce qui a le plus de sens.

2 votes

Est-ce que c'est juste un hack ? document.getElementById("myform").foo ; Après avoir étudié un peu le DOM, je ne comprends pas pourquoi cela fonctionne. Je pense que l'objet formulaire est aussi un tableau de ses éléments enfants indexés sur l'attribut html name...

1 votes

Vous mentionnez également que "le nom n'est pas transmis au serveur dans le cadre du POST/GET et ne fonctionne pas pour les signets de type hachage". N'est-ce pas précisément ce qui est transmis au serveur ? Lorsque vous travaillez avec PHP, c'est l'attribut name qui constitue votre index dans le global $_POST.

2 votes

@Justin, c'est l'attribut nom qui est transmis au serveur.

14voto

Sergey Ilinsky Points 16803

Pour accéder aux éléments nommés placés dans un formulaire, il est bon d'utiliser la fonction form l'objet lui-même.

Pour accéder à un élément arbitraire dans l'arbre DOM qui peut parfois se trouver dans un formulaire, utilisez getElementById et l'élément id .

10 votes

Que voulez-vous dire par "utiliser l'objet formulaire lui-même" ? Une fois que vous avez l'objet formulaire, quelle méthode utilisez-vous pour accéder à un élément particulier ?

2 votes

Je veux dire que je recommanderais d'utiliser N5 (document.getElementById('myForm').elements.foo) pour accéder aux éléments nommés et N6 (document.getElementById('myForm').elements) pour accéder à la collection itérable d'éléments

0 votes

Je suis en train de définir le style de mon code... et de préférence, je m'en tiens aux IDs.... de façon à ce que l'accès aux éléments soit cohérent sur toute la page. + les autres raisons mentionnées.

9voto

Robin Richmond Points 43

Je préfère de loin une 5ème méthode. C'est-à-dire
[5] Utilisez l'identifiant spécial JavaScript este pour transmettre l'objet formulaire ou champ à la fonction depuis le gestionnaire d'événements.

Plus précisément, pour les formulaires :

<form id="form1" name="form1" onsubmit="return validateForm(this)">

et

// The form validation function takes the form object as the input parameter
function validateForm(thisForm) {
  if (thisform.fullname.value !=...

En utilisant cette technique, la fonction ne doit jamais savoir
- l'ordre dans lequel les formulaires sont définis dans la page,
- l'ID du formulaire, ni
- le nom du formulaire

De même, pour les champs :

<input type="text" name="maxWeight">
...
<input type="text" name="item1Weight" onchange="return checkWeight(this)">
<input type="text" name="item2Weight" onchange="return checkWeight(this)">

et

function checkWeight(theField) {
  if (theField.value > theField.form.maxWeight.value) {
    alert ("The weight value " + theField.value + " is larger than the limit");
    return false;
  }
return true;
}

Dans ce cas, la fonction n'a jamais besoin de connaître le nom ou l'identifiant d'un champ de poids particulier, mais elle doit connaître le nom du champ de limite de poids.

0 votes

Je ne suis pas sûr de la cause sous-jacente, mais j'ai vu cette approche retourner des chaînes vides dans certaines circonstances, mais pas toutes.

8voto

Paul D. Waite Points 35456

Ça ne répond pas vraiment à votre question, mais juste à cette partie :

[3] requiert à la fois un identifiant et un nom... avoir les deux est quelque peu redondant

Vous aurez probablement besoin d'un id sur chaque champ de formulaire de toute façon, de sorte que vous puissiez associer l'attribut <label> avec lui, comme ceci :

<label for="foo">Foo:</label>
<input type="text" name="foo" id="foo" />

Ceci est nécessaire pour l'accessibilité (c'est-à-dire que si vous n'associez pas les étiquettes de formulaire et les contrôles, pourquoi détestez-vous autant les aveugles ?)

C'est un peu redondant, bien que cela le soit moins lorsque vous avez des cases à cocher/des boutons radio, où plusieurs d'entre eux peuvent partager une name . En fin de compte, id y name sont destinés à des fins différentes, même si les deux sont souvent fixés à la même valeur.

5 votes

Si vous enveloppez une entrée dans son étiquette, vous n'avez pas besoin d'un attribut id ou for. <label>Foo : <input type="text" name="foo" </label>

3 votes

C'est tout à fait vrai, bien que cela limite ce que vous pouvez réaliser en termes d'apparence et de sensation.

2 votes

@kennebec-vous devez toujours utiliser un id si vous voulez que l'étiquette soit associée à un élément. Les anciennes versions d'IE (< 8 ?) n'associaient pas les éléments à l'intérieur d'une étiquette à l'étiquette s'il n'y avait pas d'id correspondant. pour y id attributs.

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