Лучшая практика. Получите доступ к элементам формы по атрибуту HTML или атрибуту имени?

Как известно любому опытному разработчику JavaScript, существует много (слишком много) способов сделать то же самое. Например, скажем, что у вас есть текстовое поле следующим образом:

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

Есть много способов получить доступ к этому в JavaScript:

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

Методы [1] и [3] хорошо документированы в документации Mozilla Gecko, но ни одна из них не является идеальной. [1] является слишком общим, чтобы быть полезным, и [3] требует как идентификатора, так и имени (при условии, что вы отправляете данные на серверный язык). В идеале было бы лучше иметь только атрибут id или атрибут name (с тем, что оба они несколько избыточны, особенно если идентификатор не нужен для любого css и увеличивает вероятность опечаток и т.д.).

[2] кажется наиболее интуитивным и, по-видимому, широко используется, но я не видел его упоминания в документации Gecko, и я беспокоюсь о совместимости с обеих сторон и перекрестной совместимости браузеров (и, конечно же, я хотите быть максимально совместимыми с стандартами).

Итак, какая лучшая практика здесь? Может ли кто-нибудь указать на что-то в документации DOM или спецификации W3C, которая может разрешить это?

Примечание. Меня особенно интересует небиблиотечное решение (jQuery/Prototype).

Ответ 1

Дайте вашей форме только id, а ваш ввод - имя:

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

Тогда самый стандартизованный и наименее проблематичный способ доступа к вашему элементу ввода - через:

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

использование .elements["foo"] вместо просто .foo предпочтительнее, потому что последнее может вернуть свойство формы с именем "foo", а не элемент HTML!

Ответ 2

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

"Нет-омг-никогда!" приходит на ум, когда я вижу этот метод доступа к элементу. Проблема заключается в том, что он предполагает, что DOM является нормальной структурой данных (например, массив), в которой порядок элементов является статическим, последовательным или надежным в любом случае. Мы знаем, что 99,9999% времени, что это не так. Переупорядочение или input элементов в форме, добавление другого form к странице перед рассматриваемой формой или перемещение рассматриваемой формы - это все случаи, когда этот код ломается. Рассказ: это очень хрупкий. Как только вы добавите или переместите что-нибудь, он сломается.

[2] document.myForm.foo;

Я с Сергей Илинский по этому поводу:

  • Доступ к произвольным элементам путем ссылки на их атрибут id: document.getElementById("myform");
  • Доступ к именованным элементам формы по имени относительно элемента их родительской формы: document.getElementById("myform").foo;

Моя основная проблема с этим методом заключается в том, что атрибут name бесполезен при применении к форме. Имя не передается на сервер как часть POST/GET и не работает для закладок стиля хеш.

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

По-моему, это самый предпочтительный метод. Прямой доступ - наиболее сжатый и понятный метод.

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

По-моему, это приемлемо, но более многословно, чем необходимо. Предпочтительным является способ № 3.


Я просто так смотрел видео от Дугласа Крокфорда, и он взвесил эту тему. Интересная достопримечательность - 12: 00. Подводя итог:

  • Коллекции документов (document.anchor, document.form и т.д.) устарели и неактуальны (метод 1).
  • Атрибут name используется для обозначения вещей, а не для доступа к ним. Он предназначен для обозначения таких вещей, как окна, поля ввода и привязки.
  • "Идентификатор - это то, что вы должны использовать для уникальной идентификации элемента, чтобы вы могли получить к нему доступ. Они (имя и идентификатор) были взаимозаменяемыми, но их больше нет."

Итак, у вас это есть. Семантически это имеет смысл.

Ответ 3

Для доступа к именованным элементам, помещенным в форму, рекомендуется использовать сам объект form.

Чтобы получить доступ к произвольному элементу в дереве DOM, который иногда может быть найден в форме, используйте getElementById и элемент id.

Ответ 4

Я предпочитаю 5-й метод. Это
[5] Используйте специальный идентификатор JavaScript this, чтобы передать форму или объект поля функции из обработчика события.

В частности, для форм:

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

и

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

Используя эту технику, функция никогда не должна знать - порядок, в котором формы указаны на странице,
- идентификатор формы, ни
- имя формы

Аналогично, для полей:

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

и

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;
}

В этом случае функция никогда не должна знать имя или идентификатор определенного поля веса, хотя ему нужно знать имя поля ограничения веса.

Ответ 5

На самом деле он не отвечает на ваш вопрос, но только по этой части:

[3] требует как идентификатора, так и имени... с двумя избыточными

Скорее всего, вам нужно иметь атрибут id для каждого поля формы, так что вы можете связать его с элементом <label> следующим образом:

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

Это необходимо для доступности (т.е. если вы не ассоциируете метки форм и элементы управления, почему вы так ненавидите слепых людей?).

Это несколько избыточно, хотя и меньше, когда у вас есть флажки/переключатели, где несколько из них могут делиться name. В конечном счете, id и name предназначены для разных целей, даже если оба часто устанавливаются одинаковыми значениями.

Ответ 6

Это немного устарело, но я хочу добавить то, что, на мой взгляд, имеет значение.
(Я хотел прокомментировать один или два потока выше, но мне кажется, что мне нужна репутация 50, и у меня только 21 в то время, когда я пишу это.:))
Просто хочу сказать, что есть моменты, когда гораздо лучше получить доступ к элементам формы по имени, а не по id. Я не говорю о самой форме. Форма, ОК, вы можете дать ей идентификатор, а затем получить доступ к нему. Но если у вас есть радиокнопка в форме, гораздо проще использовать ее как один объект (получение и установка его значения), и вы можете делать это только по имени, насколько я знаю.

Пример:

<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>

Вы можете получить/установить проверочное значение переключателя R1 в целом, используя
document.mainForm.R1.value
или
document.getElementById( "MainForm" ). R1.value
Поэтому, если вы хотите иметь унитарный стиль, вы можете всегда использовать этот метод независимо от типа элемента формы. Я, я отлично понимаю, что доступ к переключателям по имени и текстовым полям по id.

Ответ 7

Будучи старомодным, я всегда использовал синтаксис "document.myform.myvar", но недавно обнаружил, что он не работает в Chrome (ОК в Firefox и IE). Это была страница Ajax (т.е. Загружена в свойство innerHTML div). Возможно, Chrome не распознал форму как элемент основного документа. Я использовал getElementById (без ссылки на форму), и он работал нормально.

Ответ 8

Форма 2 в порядке, и также рекомендуется форма 3.
Избыточность между именем и идентификатором вызвана необходимостью поддерживать совместимость, в html 5 некоторые элементы (как img, form, iframe и т.д.) Потеряют свой атрибут "name", и он рекомендует использовать только их идентификатор, чтобы ссылаться на них с этого момента on:)

Ответ 9

Посмотрите эту страницу: https://developer.mozilla.org/En/DOM/Document.getElementsByName

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

Он должен быть "элементами" и должен возвращать массив, потому что более одного элемента могут иметь одно и то же имя.

Ответ 10

Чтобы дополнить другие ответы, document.myForm.foo - это так называемый уровень DOM 0, который реализуется Netscape и, таким образом, не является открытым стандартом, хотя он поддерживается большинством браузеров.

Ответ 11

Мой ответ будет отличаться точным вопросом. Если я хочу получить доступ к определенному элементу, я буду использовать document.getElementById(). Например, вычисление полного имени человека, поскольку оно построено на нескольких полях, но оно является повторяемой формулой.

Если я хочу получить доступ к элементу как части функциональной структуры (формы), тогда я буду использовать:

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

Так оно и работает с точки зрения бизнеса. Изменения внутри цикла согласуются с функциональными изменениями в приложении, и поэтому они имеют смысл. Я применяю его в основном для удобной проверки и предотвращения сетевых вызовов для проверки неверных данных. Я повторяю сервер проверки валидации (и добавляю туда еще несколько), но если я могу помочь стороне клиента, то это полезно для всех.

Для агрегирования данных (например, построения круговой диаграммы на основе данных в форме) я использую файлы конфигурации и созданные Javascript объекты. Тогда точное значение поля важно для его контекста, и я использую document.getElementById().

Ответ 12

Просто чтобы добавить ко всему уже сказанному, вы можете получить доступ к input либо по name либо по id используя предпочтительно свойство elements формы Object, потому что без него вы можете получить свойство формы с именем "foo", а не элемент HTML. И, по словам Пола Д. Уэйта, совершенно нормально иметь как имя, так и идентификатор.

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>

Ответ 13

Я предпочитаю этот

document.forms['idOfTheForm'].nameOfTheInputFiled.value;