Имя элемента в JavaScript: атрибут name и его применение в DOM

Раздел: Веб-разработка -> DOM API

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

Основные способы работы с именем элемента

Как получить или изменить атрибут name у элемента, поддерживающего встроенное свойство name?

Наиболее прямой путь - использование свойства .name у тех HTML-элементов, для которых атрибут name является стандартным: input, form, button, textarea, select, fieldset, iframe и других. Пример:


<input type="text" id="user" name="username" value="John">
<script>
  const input = document.getElementById('user');
  console.log(input.name); // "username"
  input.name = 'newName';
  console.log(input.getAttribute('name')); // "newName" (атрибут синхронизирован)
</script>

Js id (идентификатор элемента в javascript)

Присваивание свойству .name автоматически обновляет атрибут, и наоборот - изменение атрибута через setAttribute меняет свойство. Это удобно, когда требуется изменить имя ввода динамически.

Проблема: Если обратиться к .name у элемента, не имеющего встроенного свойства (например, div), возвращается undefined. Однако атрибут name может быть установлен в HTML, он будет доступен только через getAttribute. Свойство .name не создаётся автоматически.

Решение: Использовать универсальный метод getAttribute('name') или проверять наличие свойства через in.

Как получить имя у любого элемента, даже если у него нет встроенного свойства name?

Методы getAttribute и setAttribute работают со всеми элементами, включая div, span, section и пр. Пример:


<div id="myDiv" name="container">Контент</div>
<script>
  const div = document.getElementById('myDiv');
  console.log(div.getAttribute('name')); // "container"
  console.log(div.name); // undefined
  div.setAttribute('name', 'newContainer');
  console.log(div.getAttribute('name')); // "newContainer"
</script>

Js name (имя элемента в javascript)

Этот подход подходит для любых атрибутов, даже нестандартных. Однако следует помнить, что для элементов форм свойство .name синхронизируется с атрибутом, а для остальных - нет.

Ошибка: Использование setAttribute('name', ...) на элементе формы не всегда обновляет свойство .name в старых браузерах. В современных браузерах синхронизация корректна.

Как использовать кастомные имена через data-атрибуты?

Для хранения пользовательских имён, не конфликтующих со стандартным атрибутом name, удобно применять атрибуты data-* и свойство dataset. Пример:


<button id="btn" data-action="submit" data-name="mainBtn">Отправить</button>
<script>
  const btn = document.getElementById('btn');
  console.log(btn.dataset.name); // "mainBtn"
  btn.dataset.name = 'secondaryBtn';
  console.log(btn.getAttribute('data-name')); // "secondaryBtn"
</script>

Js элемент (элемент dom в javascript)

Такой подход не влияет на механизмы работы форм, но позволяет хранить произвольные идентификаторы. dataset автоматически преобразует имена атрибутов в camelCase (например, data-user-name становится dataset.userName).

Проблема: Если атрибут data-name уже содержит дефис, доступ через dataset требует преобразования. Например, data-my-name читается как dataset.myName.

Как получить имя тега (тип) элемента, а не атрибут name?

Свойства tagName и nodeName возвращают имя HTML-тега (например, "DIV", "INPUT"). Разница: tagName существует только у элементов, nodeName - для всех узлов (текстовых, комментариев и т.д.). Пример:


<input type="text">
<script>
  const el = document.querySelector('input');
  console.log(el.tagName); // "INPUT"
  console.log(el.nodeName); // "INPUT" (для элемента)
  console.log(document.body.tagName); // "BODY"
</script>

Это используется для проверки типа элемента, а не для получения значения атрибута name. Не путайте эти понятия.

Как получить доступ к элементам по атрибуту name через document.getElementsByName?

Метод document.getElementsByName(name) возвращает живую коллекцию (NodeList) всех элементов с заданным значением атрибута name. Пример:


<form>
  <input type="radio" name="gender" value="male"> Мужской
  <input type="radio" name="gender" value="female"> Женский
</form>
<script>
  const radios = document.getElementsByName('gender');
  console.log(radios.length); // 2
  radios[0].checked = true;
</script>

Этот способ удобен для работы с группами радио-кнопок или чекбоксов. Коллекция обновляется при изменении DOM.

Проблема: Метод getElementsByName не поддерживается в Internet Explorer 10 и ниже для элементов, отличных от форм. В современных браузерах работает корректно. Для универсальной поддержки используйте querySelectorAll('[name="..."]').

Как обратиться к элементу формы по имени через объект формы?

У объекта HTMLFormElement есть доступ к элементам по атрибуту name через свойство elements или напрямую как к свойствам формы (при условии, что имя не является зарезервированным). Пример:


<form name="myForm">
  <input name="user" value="Alice">
  <button type="button" onclick="showUser()">Показать</button>
</form>
<script>
  function showUser() {
    const form = document.forms.myForm;
    console.log(form.user.value); // "Alice"
    // или form.elements['user'].value
  }
</script>

Этот способ прост, но имеет ограничения: если имя совпадает с именем встроенного свойства формы (например, length, method), может возникнуть конфликт. В таких случаях лучше использовать form.elements.name.

Ошибка: Попытка обратиться к form.unknownName вернёт undefined, но не вызовет исключение. Если элемент не найден, следует проверять его существование.

Пример 1: Получение и изменение name у input

Пример

<input type="email" id="email" name="userEmail">
<script>
  const emailInput = document.getElementById('email');
  console.log('Первоначальное name:', emailInput.name);
  emailInput.name = 'newEmail';
  console.log('После изменения name через свойство:', emailInput.getAttribute('name'));
  emailInput.setAttribute('name', 'finalEmail');
  console.log('После setAttribute свойство name:', emailInput.name);
</script>
Первоначальное name: userEmail
После изменения name через свойство: newEmail
После setAttribute свойство name: finalEmail

Свойство .name и атрибут полностью синхронизированы.

Пример 2: Использование getAttribute для div с атрибутом name

Пример

<div id="box" name="mainBox">Блок</div>
<script>
  const box = document.getElementById('box');
  console.log('Через getAttribute:', box.getAttribute('name'));
  console.log('Через свойство .name:', box.name);
  // Установка атрибута
  box.setAttribute('name', 'secondaryBox');
  console.log('После setAttribute (getAttribute):', box.getAttribute('name'));
  console.log('После setAttribute (.name):', box.name);
</script>
Через getAttribute: mainBox
Через свойство .name: undefined
После setAttribute (getAttribute): secondaryBox
После setAttribute (.name): undefined

Для элементов без встроенного name свойство .name остаётся undefined.

Пример 3: Работа с data-атрибутами как альтернативой name

Пример

<section id="section1" data-name="intro" data-group="main">Секция</section>
<script>
  const section = document.getElementById('section1');
  console.log('data-name через dataset:', section.dataset.name);
  console.log('data-group через dataset:', section.dataset.group);
  // Изменение через dataset
  section.dataset.name = 'conclusion';
  console.log('Обновлённый атрибут data-name:', section.getAttribute('data-name'));
  // Добавление нового атрибута
  section.dataset.order = 'last';
  console.log('Новый атрибут data-order:', section.getAttribute('data-order'));
</script>
data-name через dataset: intro
data-group через dataset: main
Обновлённый атрибут data-name: conclusion
Новый атрибут data-order: last

Пример 4: Получение tagName и nodeName

Пример

<p id="text">Абзац</p>
<script>
  const p = document.getElementById('text');
  console.log('tagName:', p.tagName);
  console.log('nodeName:', p.nodeName);
  console.log('nodeType:', p.nodeType); // 1 - элемент
  // nodeName для текстового узла
  const textNode = p.firstChild;
  console.log('Текстовый узел nodeName:', textNode.nodeName); // "#text"
  // tagName у текстового узла нет
  console.log('textNode.tagName:', textNode.tagName); // undefined
</script>
tagName: P
nodeName: P
nodeType: 1
Текстовый узел nodeName: #text
textNode.tagName: undefined

Пример 5: Поиск элементов по name с помощью getElementsByName

Пример

<form>
  <input type="checkbox" name="hobby" value="reading"> Чтение
  <input type="checkbox" name="hobby" value="sport"> Спорт
  <input type="checkbox" name="hobby" value="music"> Музыка
</form>
<script>
  const hobbies = document.getElementsByName('hobby');
  console.log('Найдено элементов:', hobbies.length); // 3
  hobbies[1].checked = true;
  console.log('Второй элемент отмечен:', hobbies[1].checked); // true
  // Изменение атрибута name у одного элемента
  hobbies[0].name = 'other';
  console.log('После изменения name у первого:', document.getElementsByName('hobby').length); // 2 (живая коллекция)
</script>
Найдено элементов: 3
Второй элемент отмечен: true
После изменения name у первого: 2

Пример 6: Динамическое создание элемента с атрибутом name

Пример

<script>
  const newInput = document.createElement('input');
  newInput.type = 'text';
  newInput.setAttribute('name', 'dynamicField');
  newInput.value = 'Значение';
  document.body.appendChild(newInput);
  // Теперь можно получить через getElementsByName
  const dynEl = document.getElementsByName('dynamicField');
  console.log('Созданный элемент:', dynEl[0].value);
  // Альтернатива - свойство name после добавления
  console.log('Свойство name:', dynEl[0].name);
</script>
Созданный элемент: Значение
Свойство name: dynamicField

Для input свойство name появилось автоматически, так как оно поддерживается.

Пример 7: Проблема с .name для элемента без встроенного свойства

Пример

<span id="label" name="errorLabel">Ошибка</span>
<script>
  const span = document.getElementById('label');
  console.log('Попытка .name:', span.name); // undefined
  console.log('getAttribute:', span.getAttribute('name')); // "errorLabel"
  // Присвоение .name не создаёт атрибут
  span.name = 'newLabel';
  console.log('После присвоения .name (getAttribute):', span.getAttribute('name')); // "errorLabel" (не изменился)
  console.log('После присвоения .name (свойство):', span.name); // "newLabel" (сохраняется как обычное свойство объекта)
</script>
Попытка .name: undefined
getAttribute: errorLabel
После присвоения .name (getAttribute): errorLabel
После присвоения .name (свойство): newLabel

Важно не путать стандартное свойство DOM и произвольное свойство JavaScript, добавленное к объекту.

Пример 8: Использование querySelectorAll для поиска по name (альтернатива getElementsByName)

Пример

<input type="hidden" name="token" value="abc123">
<script>
  const tokens = document.querySelectorAll('[name="token"]');
  console.log('Найдено:', tokens.length); // 1
  tokens[0].value = 'xyz';
  console.log('Новое значение:', tokens[0].value);
  // Недостаток: коллекция не живая (статическая)
  document.body.innerHTML += '<input type="hidden" name="token" value="def">';
  console.log('После добавления нового элемента (querySelectorAll):', document.querySelectorAll('[name="token"]').length); // 2 (новый запрос)
  console.log('После добавления (getElementsByName):', document.getElementsByName('token').length); // 2 (живая коллекция)
</script>
Найдено: 1
Новое значение: xyz
После добавления нового элемента (querySelectorAll): 2
После добавления (getElementsByName): 2

Выбор между живой и статической коллекцией зависит от задачи: при динамических изменениях DOM живая коллекция обновляется автоматически, но может снижать производительность.

Имя элемента в JavaScript - comments

En
Js name (javascript)