Рекомендация. Доступ к элементам формы по идентификатору HTML или атрибуту имени? - PullRequest
121 голосов
/ 12 марта 2010

Как знает любой опытный разработчик 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).

Ответы [ 11 ]

83 голосов
/ 12 февраля 2014

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

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

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

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

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

32 голосов
/ 12 марта 2010

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

" No-omg-never! " приходит на ум, когда я вижу этот метод доступа к элементам. Проблема заключается в том, что предполагается, что 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 используется для именования вещей, а не для доступа к ним. Он предназначен для именования таких вещей, как окна, поля ввода и теги привязки.
  • «Идентификатор - это то, что вы должны использовать для уникальной идентификации элемента, чтобы вы могли получить к нему доступ. Они (имя и идентификатор) раньше были взаимозаменяемыми, но они больше не являются.»

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

14 голосов
/ 12 марта 2010

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

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

элемента
7 голосов
/ 02 мая 2013

Я предпочитаю 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;
}

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

6 голосов
/ 13 марта 2010

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

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

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

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

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

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

4 голосов
/ 31 марта 2017

Это немного устарело, но я хочу добавить кое-что, что я считаю уместным.
(Я хотел прокомментировать одну или две темы выше, но мне кажется, что мне нужна репутация 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
Поэтому, если вы хотите иметь унитарный стиль, вы можете использовать этот метод всегда, независимо от типа элемента формы. Я, мне очень удобно получать доступ к переключателям по имени и по текстовым полям по идентификатору.

2 голосов
/ 26 ноября 2013

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

0 голосов
/ 29 ноября 2013

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

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

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

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

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

0 голосов
/ 26 февраля 2012

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

0 голосов
/ 12 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...