Работа с атрибутами и свойствами элементов в JavaScript
В этой статье познакомимся DOM-свойствами и атрибутами, рассмотрим, чем они отличаются и как правильно с ними работать. Разберём какие в JavaScript есть методы для выполнения операций над атрибутами.
Чем отличается атрибут от DOM-свойства
Атрибуты — это HTML-сущности, с помощью которых мы можем добавить определённые данные к элементам в HTML-коде.
Когда браузер запрашивает некоторую страницу, он получает её исходный HTML-код. После этого он парсит этот код и строит на его основании DOM. Во время этого процесса HTML-атрибуты элементов переводятся в соответствующие DOM-свойства.
Например, браузер, при чтении следующей HTML-строчки кода, создаст для этого элемента следующие DOM-свойства: id
, className
, src
и alt
.
<img id="brand" class="brand" src="logo.png" alt="логотип сайта">
Обращение к этим свойствам в коде JavaScript выполняется как к свойствам объекта. Объектом здесь выступает узел (элемент) DOM.
Пример, в котором получим значения DOM-свойств для элемента, приведённого выше, и выведем их значения в консоль:
// получим элемент var brandImg = document.querySelector('#brand'); // выведем в консоль значения DOM-свойств элемента console.log(brandImg.id); // "brand" console.log(brandImg.className); // "brand" console.log(brandImg.src); // "logo.png" console.log(brandImg.alt); // "логотип сайта"
Некоторые названия DOM-свойств не соответствуют именам атрибутов. Одним из таких является атрибут class
. Данному атрибуту соответствует DOM-свойство className
. Данное отличие связано с тем, что class
является ключевым словом в JavaScript, оно зарезервировано и не может использоваться. Из-за этого разработчики стандарта решили использовать для соответствия какое-то другое название, в качестве которого было выбрано className
.
Ещё один нюанс связан с тем, что перевод HTML-атрибутов, заданных в исходном коде документа, в DOM-свойства не всегда осуществляется один к одному.
Если элемент имеет нестандартный HTML-атрибут, то свойство, соответствующее ему в DOM, не создаётся.
<div id="mydiv" alt="..."></div> <script> // получим элемент mydiv = document.querySelector('#mydiv'); // получим значение свойство alt элемента и выведем его в консоль console.log(mydiv.alt); // undefined // получим значение атрибут alt элемента и выведем его в консоль console.log(mydiv.getAttribute('alt')); // "..." </script>
Другое отличие связано с тем, что значения определённых HTML-атрибутов и соответствующих им DOM-свойств могут быть различными. Т.е. атрибут может иметь одно значение, а DOM-свойство, созданное на его основе – другое.
Одним из таких атрибутов является checked
.
<input type="checkbox" checked>
Значение HTML-атрибута checked
в данном случае – это пустая строка. Но, свойство, соответствующее данному атрибуту в DOM, будет иметь значение true
. Т.к. по правилам стандарта для установления true
достаточно лишь упоминание этого атрибута в HTML-коде и при этом не важно какое он будет иметь значение.
При этом даже если мы в HTML-коде не укажем атрибут checked
для элемента input
с типом checkbox
, то для него в DOM всё равно будет создано свойство checked
, но оно будет равно false
.
<input type="checkbox">
Кроме этого, JavaScript позволяет также работать с атрибутами. Для этого в DOM API имеются специальные методы. Но их желательно использовать только тогда, когда вам действительно нужно работать с данными именно так.
При этом нужно знать, что, когда мы изменяем DOM-свойство элемента, изменяется и соответствующий ему атрибут, и наоборот. Но это процесс в браузерах выполнятся не всегда один к одному.
Основные отличия между DOM-свойствами и атрибутами:
- значение атрибута – это всегда строка, а значение DOM-свойства – определённый тип данных (не обязательно строка);
- имя атрибута – регистронезависимо, а DOM-свойства - регистрозависимо. Т.е. в HTML-коде мы можем, например, HTML-атрибут
id
написать, какId
,ID
и т.д. То же касается и имени атрибута, которые мы указываем в специальных методах JavaScript для работы с ним. Но к соответствующему DOM-свойству мы можем обратиться только поid
и никак по-другому.
Работа с DOM-свойствами элемента
Работа со свойствами элементов в JavaScript как уже было отмечено выше осуществляется как со свойствами объектов.
Но для того, чтобы обратиться к свойству некоторого элемента, его необходимо сначала получить. Получить DOM-элемент в JavaScript можно, например, с помощью универсального метода querySelector
, а коллекцию DOM элементов, например, посредством querySelectorAll
.
В качестве первого примера рассмотрим следующий HTML-элемент:
<div id="alert" class="alert alert-info" title="Текст подсказки..."> Текст информационного сообщения... </div> <script> var alert = document.querySelector('#alert'); // получим элемент </script>
На базе него разберём как осуществляется получение DOM-свойств, их изменение и добавление новых.
Чтение значений DOM-свойств:
// получим значение DOM свойства id var alertId = alert.id; // "alert" // получим значение DOM свойства className var alertClass = alert.className; // "alert alert-info" // получим значение DOM свойства title var alertId = alert.title; // "Текст подсказки..."
Изменение значений DOM-свойств:
// для изменения значения DOM свойству, ему нужно просто присвоить новое значение alert.title = "Новый текст подсказки"; // присвоим DOM-свойству title элемента новое значение // или так (т.к. обращение к этому свойству мы уже сохранили в переменную alertId) alertId = "Новый текст подсказки"; // или так (т.к. обращение к этому свойству мы уже сохранили в переменную alertId) alert.className = "alert alert-warning";
Добавление DOM-свойств:
alert.lang = "ru"; // установим свойству lang значение равное "ru" alert.dir = "ltr"; // установим свойство dir значение равное "ltr"
Пример, в котором выведем в консоль все значения классов, которые есть у элементов p
на странице:
var paragraphs = document.querySelectorAll("p"); for (var i = 0, length = paragraphs.length ; i < length; i++) { if (paragraphs[i].className) { console.log(paragraphs[i].className); }
Пример, в котором установим всем элементам с классом content
свойство lang
со значением "ru":
var contents = document.querySelectorAll('.content'); for (var i = 0, length = contents.length; i < length; i++) { contents[i].lang = "ru"; }
Атрибуты элементов и методы для работы с ними
Атрибуты изначально задаются в HTML-коде. Они хоть и связаны, некоторым образом, со свойствами, но это не одно и тоже. В большинстве случаев следует работать именно со свойствами, а к атрибутам обращаться только тогда, когда это действительно нужно.
Значения атрибутов, в отличие от DOM-свойств, как это уже было отмечено выше всегда является строкой.
В JavaScript для выполнения операций, связанных с атрибутами, имеется четыре метода:
.hasAttribute('имя_атрибута')
– проверяет наличие указанного атрибута у элемента. Если проверяемый атрибут есть у элемента, то данный метод возвращаетtrue
, в противном случае -false
..getAttribute('имя_атрибута')
– получает значение атрибута. Если указанного атрибута нет у элемента, то данный метод возвращает пустую строку ("") илиnull
..setAttribute('имя_атрибута', 'значение_атрибута')
– устанавливает указанный атрибут с указанным значением элементу. Если указанный атрибут есть у элемента, то данный метод тогда просто изменит ему значение..removeAttribute('имя_атрибута')
- удаляет указанный атрибут у элемента.
Рассмотрим примеры.
Очень интересный пример с атрибутом value
.
Пример с атрибутом value
<input name="name" type="text" value="Bob"> <script> var name = document.querySelector('input[name="name"]'); // получим элемент </script>
Получим значение атрибута value
и DOM-свойства value
:
// получим значение атрибута value у элемента name.getAttribute('value'); // "Bob" // получим значение DOM-свойства value name.value; // "Bob" // обновим значение атрибута value, установим ему новое значение name.setAttribute('value', 'Tom'); // "Tom" // получим значение DOM свойства value name.value; // "Tom"
Из этого примера видно, что, при измении атрибута value
, браузер автоматически изменяет в соответствии с ним DOM-свойство value
.
Теперь давайте проделаем действия, наоборот, а именно изменим значение DOM-свойства и проверим изменится ли значение атрибута:
// установим новое значение DOM-свойству value name.value = "John"; // получим значение атрибута value у элемента name.getAttribute('value'); // "Tom"
Из этого примера видно, что не всегда изменение DOM-свойства приводит к соответствующему изменению атрибута. Т.е. в этом случае изменение DOM-свойства value не изменяет соответствующий ему атрибут.
Тоже самое произойдёт, когда пользователь будет вводить текст в это поле. В DOM-свойстве value
будет находится действительное значение, а в соответствующем ему атрибуте изначальное или то, которое мы установили, например, с помощью метода setAttribute
.
Этот пример показывает, что более корректно работать всегда с DOM-свойствами, а обращаться к атрибуту нужно только тогда, когда это действительно необходимо.
Даже в случае, когда вам нужно получить начальное значение value
, которое мы установили в HTML, можно воспользоваться свойством. Свойство, содержащее начальное значение атрибута value
называется defaultValue
.
name.defaultValue; // Tom
Ещё один очень интересный пример, но теперь с атрибутом href.
Пример с атрибутом href
Пример, в котором нам нужно получить значение ссылки так, как оно было установлено в HTML.
<a id="link" href="page2.html"></a> <script> var page2 = document.querySelector('#link'); page2.getAttribute('href'); // page2.html page2.href; // полный URL, например: http://localhost/page2.html </script>
В этом примере атрибут href
и DOM-свойство href
содержат разные значения. В атрибуте href
- то, что мы установили в коде, а в DOM-свойстве - полный URL. Это различие продиктовано стандартом, в соответствии с которым браузер должен привести значение href
к полному URL.
Поэтому если нам нужно получить то, что находится в атрибуте, то без метода getAttribute
в этом случае не обойтись.
В завершении разберём ещё атрибут selected
.
Пример с атрибутом selected
Пример, в котором показано как можно получить значение выбранной опции select
:
<select id="mark"> <option value="none" selected>нет оценки</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> <script> // получаем элемент select var mark = document.querySelector('#mark'); // 1 способ mark.querySelector('option:checked').value; // 2 способ mark.value; </script>
Пример, в котором показано как можно получить выбранные значения опций в элементе select
:
<select id="mark" multiple> <option value="none" selected>нет оценки</option> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </select> <script> // получаем элемент select var mark = document.querySelector('#mark'); // 1 способ (через создание массива и наполнением его значений выбранных опций) var arr = []; for (var i = 0, length = mark.options.length; i < length; i++) { if (mark.options[i].selected) { arr.push(mark.options[i].value); } } // 2 способ (более современный, с использованием DOM-свойства selectedOptions) var arr = Array.from(mark.selectedOptions, option => option.value) </script>
Ещё один способ работы с атрибутами (свойство attributes)
В JavaScript у каждого элемента имеется свойство attributes
, с помощью которого можно получить все его атрибуты в виде объекта NamedNodeMap
.
Данный способ может находить применение, когда вам нужно, например перебрать все атрибуты элемента.
Доступ к атрибуту в этой коллекции осуществляется по его индексу или с помощью метода item
. Отсчёт атрибутов в этой коллекции ведётся с 0.
Например, выведем в консоль все атрибуты некоторого элемента:
<p id="message" class="text" style="text-align: center;">I LOVE JAVASCRIPT</p> <script> // получим элемент по его идентификатору message var message = document.querySelector('#message'); // получим его атрибуты var attrs = message.attributes; // переберём все атрибуты с помощью цикла (attrs.length – количество атрибутов) for (var i = 0, length = attrs.length; i < length; i++) { // attrs[i] или attrs.item(i) – обращение к атрибуту в коллекции по его порядковому номеру // attrs[i].name – имя атрибута // attrs[i].value – значение атрибута (с помощью него можно также изменить значение атрибута) console.log(attrs[i].name + ' = ' + attrs[i].value); // или с помощью метода item console.log(attrs.item(i).name + ' = ' + attrs.item(i).value); // пример как можно изменить значение через свойство value // if (attrs[i].name === "class") { // attr[i].value = "info"; // } } // в результате выполнения: // id = message // class = text // style = text-align: center; </script>
Кроме этого, работать с этой коллекцией можно также посредством следующих методов:
.getNamedItem('имя_aтpибyтa')
– получает значение указанного атрибута (если указанный атрибут отсутствует у элемента, то в качестве результата получимnull
)..setNamedItem('aтpибyт_yзeл')
– добавляет новый атрибут к элементу или обновляет значение у существующего. Для создания атрибута необходимо использовать методdocument.createAttribute()
, которому в качестве параметра необходимо передать имя атрибута. После этого созданному атрибуту необходимо присвоить значение с помощью свойстваvalue
..removeNamedItem('имя_атрибута')
– удаляет указанный атрибут у элемента (в качестве результата возвращает удалённый атрибут).
Пример, работы с атрибутами через методы getNamedItem, setNamedItem и removeNamedItem:
<p id="message" class="text" style="text-align: center;">I LOVE JAVASCRIPT</p> <script> // получим элемент по его идентификатору message var message = document.querySelector('#message'); // получим его аттрибуты var attrs = message.attributes; // Задача №1. Получим значение атрибута id console.log(attrs.getNamedItem('id')); // Задача №2. Установим атрибут (если он есть, то изменим его значение, в противном случае добавим новый) // создаём атрибут style и сохраняем его в переменную attrStyle var attrStyle = document.createAttribute('style'); // присваиваем значение атрибуту с помощью свойства value attrStyle.value = 'text-align: left;'; // устанавливаем атрибут элементу attrs.setNamedItem(attrStyle); // Задача №3. удалить атрибут class у элемента attrs.removeNamedItem("class"); </script>
Задачи
- Вывести в консоль все элементы документа, которые имеют атрибут
id
. - Добавить атрибут
title
ко всем изображениям на странице, если данного атрибута у них нет. Значение атрибута установить равным значению атрибутаalt
.
Комментарии: 4
Александр, добрый день!
Не подскажите, возможно ли установить элементу несколько атрибутов (не css стили, а именно html параметры) в одну строку? Например:
Хотелось бы реализовать по такому типу:
но так не работает..
Метод getAttribute('checked') возвращает null, хотя такой атрибут у элемента есть.
Когда браузер читает HTML документ, он генерирует на её основе DOM. При этом все стандартные атрибуты становятся DOM-свойствами. При этом атрибуты и DOM-свойства хоть на первый взгляд кажутся похожими, но это не одно и тоже.
Т.е. изначально вы создали в HTML-документе элемент:
Когда браузер прочитал этот код, он создал в DOM элемент input и свойству checked установил значение false. Но значение атрибута осталось без изменений. Вот такая особенность.
В этом случае чтобы узнать его состояние, нам нужно обратиться именно к DOM-свойству элемента:
Если же мы обратимся к значению атрибута checked, то получим null. Т.к. у элемента данного атрибута нет:
Теперь если мы нажмём на него, мы изменим его состояние на true (его свойство):
Но на атрибут это изменение браузер не отобразит, т.к. уж особенность:
Просто у нас есть 2 разные вещи: DOM-свойства и атрибуты. Это не одно и тоже.
При этом состояние checked правильно получать посредством DOM-свойства checked.
Например, если провести эксперимент дальше и, например в HTML-документе создать следующий код:
Т.е. сразу установить checkbox во включенное состояние.
При этом, получая DOM-свойство checked данного элемента, вы получите true:
А получая значение атрибута checked, вы получите пустую строку: