web-dev-qa-db-fra.com

Meilleure pratique: accéder aux éléments de formulaire par un identifiant HTML ou un attribut de nom?

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

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

Il y a plusieurs façons d'accéder à cela 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 décrites dans la documentation de Mozilla Gecko, mais elles ne sont pas non plus idéales. [1] est trop général pour être utile et [3] nécessite à la fois un identifiant et un nom (en supposant que vous publierez les données dans une langue côté serveur). Idéalement, il serait préférable d’avoir uniquement un attribut id ou un attribut name (les deux étant quelque pe = redondants, surtout si l’id n’est pas nécessaire pour les fichiers CSS, et augmente le risque de fautes de frappe, etc. ).

[2] semble être le plus intuitif et semble être largement utilisé, mais je ne l’ai pas vu référencé dans la documentation de Gecko et je suis inquiet à la fois pour la compatibilité en aval et la compatibilité entre navigateurs (et bien sûr, je veux être conforme aux normes que possible).

Alors, quelle est la meilleure pratique ici? Quelqu'un peut-il indiquer quelque chose dans la documentation DOM ou dans la spécification W3C qui pourrait résoudre ce problème?

Remarque Je suis particulièrement intéressé par une solution non basée sur une bibliothèque (jQuery/Prototype).

127
seth

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

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

Ensuite, le moyen le plus conforme aux normes et le moins problématique d'accéder à votre élément d'entrée consiste à:

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

il est préférable d'utiliser .elements["foo"] au lieu de .foo, car ce dernier peut renvoyer une propriété de la forme nommée "foo" plutôt qu'un élément HTML!

86
Doin

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

" No-omg-never! " me vient à l'esprit lorsque je vois cette méthode d'accès à l'élément. Le problème avec ceci est qu’il suppose que le DOM est une structure de données normale (un tableau par exemple) dans laquelle l’ordre des éléments est statique, cohérent ou fiable de toute façon. Nous savons que 99,9999% du temps, que ce n'est pas le cas. Réorganiser ou input éléments dans le formulaire, ajouter un autre form à la page précédant le formulaire en question ou déplacer le formulaire en question sont tous des cas où ce code est rompu. Petite histoire: c'est très fragile. Dès que vous ajoutez ou déplacez quelque chose, ça va casser.

[2] document.myForm.foo;

Je suis avec Sergey ILinsky à ce sujet:

  • Accédez à des éléments arbitraires en vous référant à leur attribut id: document.getElementById("myform");
  • Accédez 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 l'attribut 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 style de 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, cela est acceptable, mais plus verbeux que nécessaire. La méthode n ° 3 est préférable.


Il m'est arrivé de regarder un vidéo de Douglas Crockford et il a pesé à ce sujet. Le point d'intérêt est à -12h00. Résumer:

  • Les collections de documents (document.anchor, document.form, etc.) sont obsolètes et sans intérêt (méthode 1).
  • L'attribut name est utilisé pour nommer des choses, pas pour y accéder. C'est pour nommer des choses comme des fenêtres, des champs de saisie et des balises d'ancrage.
  • "L'identifiant est l'élément que vous devez utiliser pour identifier de manière unique un élément afin de pouvoir y accéder. Ils (nom et identifiant) étaient auparavant interchangeables, mais ils ne le sont plus."

Donc là vous l'avez. Sémantiquement, cela a le plus de sens.

33
Justin Johnson

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

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

14
Sergey Ilinsky

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

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 n'a jamais besoin de savoir
- l'ordre dans lequel les formulaires sont définis dans la page,
- l'identifiant 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'id d'un champ de poids particulier, bien qu'elle ait besoin de connaître le nom du champ de limite de poids.

8
Robin Richmond

Ce n’est pas vraiment répondre à votre question, mais juste sur cette partie:

[3] requiert à la fois un identifiant et un nom ... les deux étant quelque pe redondant

De toute façon, vous aurez probablement besoin d’un attribut id sur chaque champ de formulaire pour pouvoir y associer son élément <label>, comme ceci:

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

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

Il est quelque peu redondant, mais moins lorsque vous avez des cases à cocher/boutons radio, où plusieurs peuvent partager un name. En fin de compte, id et name ont des objectifs différents, même si les deux sont souvent définis sur la même valeur.

7
Paul D. Waite

C'est un peu vieux mais je veux ajouter quelque chose de pertinent.
(Je voulais commenter une ou deux des discussions ci-dessus, mais il me semble que j'ai besoin de la réputation 50 et que j'en ai seulement 21 au moment où j'écris ceci. :))
Je veux juste dire qu’il est parfois préférable d’accéder aux éléments d’un formulaire par son nom plutôt que par son identifiant. Je ne parle pas de la forme elle-même. Le formulaire, OK, vous pouvez lui donner un identifiant puis y accéder. Mais si vous avez un bouton radio dans un formulaire, il est beaucoup plus facile de l'utiliser comme un seul objet (obtenir et définir sa valeur) et vous ne pouvez le faire que par nom, à ma connaissance.

Exemple:

<form id="mainForm" name="mainForm">
    <input type="radio" name="R1" value="V1">choice 1<br/>
    <input type="radio" name="R1" value="V2">choice 2<br/>
    <input type="radio" name="R1" value="V3">choice 3
</form>

Vous pouvez obtenir/définir la valeur cochée du bouton radio R1 dans son ensemble en utilisant
document.mainForm.R1.value
ou
document.getElementById ("mainForm"). R1.value
Donc, si vous souhaitez avoir un style unitaire, vous pouvez toujours vouloir utiliser cette méthode, quel que soit le type d'élément de formulaire. Moi, je suis parfaitement à l'aise pour accéder aux boutons radio par nom et aux zones de texte par identifiant.

4
VSim

Étant démodé, j’ai toujours utilisé la syntaxe 'document.myform.myvar' mais j’ai récemment constaté un échec dans Chrome (OK dans Firefox et IE). C'était une page Ajax (c'est-à-dire chargée dans la propriété innerHTML d'un div). Peut-être que Chrome n'a pas reconnu le formulaire en tant qu'élément du document principal. J'ai utilisé getElementById (sans faire référence au formulaire) à la place et cela a fonctionné correctement.

2
Captain Nemo

La formule 2 est acceptable et la formule 3 est également recommandée.
La redondance entre name et id est due à la nécessité de conserver la compatibilité. En HTML 5, certains éléments (tels que img, form, iframe, etc.) perdront leur attribut "name" et il est recommandé d'utiliser uniquement leur identifiant. pour les référencer à partir de maintenant :)

0
wintermute

Consultez cette page: https://developer.mozilla.org/En/DOM/Document.getElementsByName

document.getElementsByName('foo')[0]; // returns you element.

Il doit s'agir d'éléments et doit renvoyer un tableau car plusieurs éléments peuvent porter le même nom.

0
robert

Ma réponse différera sur la question exacte. Si je veux accéder à un élément en particulier, vais-je utiliser document.getElementById (). Un exemple consiste à calculer le nom complet d'une personne, car il repose sur plusieurs champs, mais il s'agit d'une formule répétable.

Si je veux accéder à l'élément en tant que partie d'une structure fonctionnelle (un formulaire), puis-je utiliser:

var frm = document.getElementById('frm_name');
for(var i = 0; i < frm.elements.length;i++){
   ..frm.elements[i]..

C'est ainsi que cela fonctionne également du point de vue de l'entreprise. Les changements dans la boucle vont de pair avec les changements fonctionnels dans l'application et sont donc significatifs. Je l'applique principalement pour la validation conviviale et pour empêcher les appels réseau de vérifier les données erronées. Je répète le côté serveur de validation (et en rajoute quelques-uns), mais si je peux aider le côté client, ce sera bénéfique pour tous.

Pour l'agrégation de données (comme la création d'un camembert basé sur les données du formulaire), j'utilise des documents de configuration et des objets Javascript personnalisés. Alors la signification exacte du champ est-elle importante par rapport à son contexte et dois-je utiliser document.getElementById ().

0
Loek Bergman

Pour ajouter à tout ce qui a déjà été dit, vous pouvez accéder à la inputs avec la name ou id en utilisant de préférence la propriété elements de la forme Object, car sans elle, obtenir une propriété de la forme nommée "foo" plutôt qu'un élément HTML. Et selon Paul D. Waite, il est parfaitement correct d'avoir à la fois le nom et l'identifiant.

var myForm = document.getElementById("myform")
console.log(myForm.foo.value) // hey
console.log(myForm.foo2.value) // hey
//preferable
console.log(myForm.elements.foo.value) // hey
console.log(myForm.elements.foo2.value) // hey
<form id="myform">
  <input type="text" name="foo" id="foo2" value="hey">
</form>

Selon MDN sur la page HTMLFormElement.elements

Les éléments de la propriété HTMLFormElement retournent un HTMLFormControlsCollection répertoriant tous les contrôles de formulaire contenus dans l'élément. Indépendamment, vous pouvez obtenir uniquement le nombre de contrôles de formulaire à l'aide de la propriété length.

Vous pouvez accéder à un contrôle de formulaire particulier dans la collection renvoyée en utilisant soit un index, soit le nom de l'élément ou id .

0

Je préfère celui-ci

document.forms['idOfTheForm'].nameOfTheInputFiled.value;
0
Fahim Md. Riaz

Pour compléter les autres réponses, document.myForm.foo est ce qu'on appelle le niveau 0 de DOM, qui est mis en œuvre par Netscape et n'est donc pas réellement un standard ouvert, même s'il est pris en charge par la plupart des navigateurs.

0
Kent Tong