Element.setAttribute()
Sets the value of an attribute on the specified element. If the attribute already exists, the value is updated; otherwise a new attribute is added with the specified name and value.
To get the current value of an attribute, use getAttribute() ; to remove an attribute, call removeAttribute() .
Syntax
Parameters
A string specifying the name of the attribute whose value is to be set. The attribute name is automatically converted to all lower-case when setAttribute() is called on an HTML element in an HTML document.
A string containing the value to assign to the attribute. Any non-string value specified is converted automatically into a string.
Boolean attributes are considered to be true if they’re present on the element at all. You should set value to the empty string ( «» ) or the attribute’s name, with no leading or trailing whitespace. See the example below for a practical demonstration.
Since the specified value gets converted into a string, specifying null doesn’t necessarily do what you expect. Instead of removing the attribute or setting its value to be null , it instead sets the attribute’s value to the string «null» . If you wish to remove an attribute, call removeAttribute() .
Return value
Exceptions
The specified attribute name contains one or more characters which are not valid in attribute names.
Examples
In the following example, setAttribute() is used to set attributes on a <button> .
Изменения в DOM
Давайте теперь рассмотрим, как добавлять, изменять, заменять и удалять узлы из DOM. В частности рассмотрим методы createElement() и createTextNode() , а также node.textContent и node.innerHTML .
Создание новых узлов
В этом разделе работаем со следующим HTML:
Открываем вкладку Console в панели разработчика.
Воспользуемся методом createElement() в объекте document для создания нового элемента p .
Успешно! Переменная paragraph выдает p элемент.
Теперь можно добавить текст к нашему элементу со свойством textContent :
Таким образом, комбинируя createElement() и textContent , можно создавать узлы-элементы.
Также можно использовать свойство innerHTML , чтобы добавлять содержимое внутрь элемента:
Из двух рассмотренных методов textContent лучше — он немного быстрее, чем innerHTML .
Текстовый узел можно создать также с помощью метода createTextNode() :
Все эти методы создают новые элементы и текстовые узлы, однако они не видны на интерфейсе веб-сайта, пока не вставлены в document !
Вставка узлов в DOM
Чтобы увидеть созданные нами текстовые узлы и элементы на интерфейсе, нужно вставить их в document . Методы appendChild() и insertBefore() используются для добавления элементов в начало, середину или конец родительского элемента, а replaceChild() используется для замены старого узла на новый.
Продемонстрируем это, добавив список к нашему HTML:
Вот наша страница:
Скажем, мы хотим добавить новый пункт в конец списка. Сперва нам нужно создать элемент и добавить к нему текст, как мы делали раньше:
Теперь у нас есть элемент для нового списка! Добавляем его в конец списка, используя appendChild() :
И новый элемент li добавлен в конец ul :
Чтобы добавить пункт в начало списка, создадим другой элемент (мы должны создать новый элемент, потому что createElement() нельзя использовать повторно):
Используем метод insertBefore() , чтобы добавить элемент в начало списка. В нем будет два аргумента: первый будет новым добавленным дочерним узлом, а второй — соседним узлом, следующим сразу за дочерним.
Так мы добавим новый элемент anotherNewItem в начало списка:
Теперь новый узел добавлен в начало списка!
Давайте теперь посмотрим, как можно заменить существующий узел новым, используя replaceChild() . Во-первых, создаем новый элемент:
Метод replaceChild() также содержит два аргумента: новый узел и узел, который нужно заменить:
В нашем примере заменяем третий дочерний элемент списка:
Используя комбинацию методов appendChild() , insertBefore() и replaceChild() узлы и элементы можно вставлять в DOM где угодно!
Удаление узлов из DOM
Для удаления узлов из DOM используем removeChild() (чтобы удалить дочерние узлы), или remove() , чтобы удалить сам узел.
Возвращаясь к нашему примеру, давайте удалим последний пункт списка:
В качестве альтернативы можно использовать remove() , чтобы удалить сам узел:
Используя removeChild() и remove() , можно удалить любые узлы из DOM.
Изменение атрибутов
Атрибуты часто используются в HTML для предоставления дополнительной информации об элементе. Некоторые распространенные примеры: атрибут src тега img , href тега a , а также class , id и style . Встречаются атрибуты, начинающиеся с data- — это пользовательские атрибуты, которые тоже можно изменять.
Вот методы, которые используются в JavaScript для изменения атрибутов:
hasAttribute() — возвращает булев тип.
getAttribute() — возвращает значение определенного атрибута.
setAttribute() — добавляет или обновляет значение определенного атрибута.
removeAttribute() — удаляет атрибут из элемента.
В качестве примера используем данный HTML:
Откроем console и протестируем методы атрибутов:
Давайте используем setAttribute() , чтобы назначить новое изображение src :
Методы hasAttribute() and getAttribute() часто используются с условными операторами, в то время как setAttribute() и removeAttribute() чаще используются для изменения DOM напрямую.
Изменение классов
В работе с CSS мы используем классы для применения стилей к нескольким элементам. Давайте посмотрим, как можно работать с атрибутом класса в JavaScript, используя className и classList .
className — получает или задает значение класса.
classList.add() —добавляет значения классов.
classList.toggle() — отобразить/скрыть класс.
classList.contains() — проверяет, существует ли определенное значение.
classList.replace() — заменяет старое значение на новое.
classList.remove() — удаляет значение.
В следующем примере поработаем с каждым из этих методов:
Начальный выводимый результат:
Используем className , чтобы применить значение к классам:
Теперь класс alert , определенный в HTML, назначен первому div :
Это изменит любые существующие классы элемента. Можно добавлять несколько классов, используя className , если разделять имена классов пробелами.
Другой способ изменять классы — использование свойства classList , у которого есть несколько полезных методов:
После запуска всех этих методов, наш HTML отобразится так:
Пометка: classList.add() добавит новый класс к списку существующих (помните, что className изменяет любые существующие классы). Также можно добавлять несколько классов строками, разделенными запятыми.
Изменение стилей
Обычно стили добавляются при помощи отдельных CSS таблиц, однако бывают случаи, когда может понадобиться использовать встроенный стиль. Полезно будет знать, как изменять его непосредственно с помощью JavaScript! Продемонстрируем с помощью следующего HTML:
При работе со свойствами CSS в DOM мы используем camelCase (верблюжий регистр). Таким образом, вместо использования тире, как в CSS, например, border-radius , мы используем camelCase borderRadius , где первое слово начинается со строчной буквы, а второе с заглавной.
Пометка: можно использовать setAttribute() для изменения стилей, например, div.setAttribute('style', 'border-radius: 50%'); , но это удалит все существующие встроенные стили, поэтому лучше использовать непосредственно атрибут style .
Вывод после добавления этих стилей:
Конечно, если нужно применить несколько изменений стиля элемента, лучше применить их к классу в CSS и просто добавить этот новый класс к элементу, используя JavaScript .
Заключение
Вот и все!! Мы поработали с деревом DOM и узлами, чтобы изучить все о доступе, прохождении и изменении элементов. Если вы прочитали все части — прекрасно! Теперь вы на пути к улучшению знаний о DOM!
Атрибуты и DOM-свойства
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-attributes-and-properties.
При чтении HTML браузер генерирует DOM-модель. При этом большинство стандартных HTML-атрибутов становятся свойствами соответствующих объектов.
Например, если тег выглядит как <body >, то у объекта будет свойство body.id = "page" .
Но это преобразование – не один-в-один. Бывают ситуации, когда атрибут имеет одно значение, а свойство – другое. Бывает и так, что атрибут есть, а свойства с таким названием не создаётся.
Если коротко – HTML-атрибуты и DOM-свойства обычно, но не всегда соответствуют друг другу, нужно понимать, что такое свойство и что такое атрибут, чтобы работать с ними правильно.
Свои DOM-свойства
Ранее мы видели некоторые встроенные свойства DOM-узлов. Но, технически, никто нас ими не ограничивает.
Узел DOM – это объект, поэтому, как и любой объект в JavaScript, он может содержать пользовательские свойства и методы.
Например, создадим в document.body новое свойство и запишем в него объект:
Можно добавить и новую функцию:
Нестандартные свойства и методы видны только в JavaScript и никак не влияют на отображение соответствующего тега.
Обратим внимание, пользовательские DOM-свойства:
- Могут иметь любое значение.
- Названия свойств чувствительны к регистру.
- Работают за счёт того, что DOM-узлы являются объектами JavaScript.
Атрибуты
Элементам DOM, с другой стороны, соответствуют HTML-теги, у которых есть текстовые атрибуты.
Конечно, здесь речь именно об узлах-элементах, не о текстовых узлах или комментариях.
Доступ к атрибутам осуществляется при помощи стандартных методов:
- elem.hasAttribute(name) – проверяет наличие атрибута
- elem.getAttribute(name) – получает значение атрибута
- elem.setAttribute(name, value) – устанавливает атрибут
- elem.removeAttribute(name) – удаляет атрибут
Эти методы работают со значением, которое находится в HTML.
Также все атрибуты элемента можно получить с помощью свойства elem.attributes , которое содержит псевдо-массив объектов типа Attr.
В отличие от свойств, атрибуты:
- Всегда являются строками.
- Их имя нечувствительно к регистру (ведь это HTML)
- Видны в innerHTML (за исключением старых IE)
Рассмотрим отличия между DOM-свойствами и атрибутами на примере HTML-кода:
Пример ниже устанавливает атрибуты и демонстрирует их особенности.
При запуске кода выше обратите внимание:
- getAttribute(‘About’) – первая буква имени атрибута About написана в верхнем регистре, а в HTML – в нижнем, но это не имеет значения, так как имена нечувствительны к регистру.
- Мы можем записать в атрибут любое значение, но оно будет превращено в строку. Объекты также будут автоматически преобразованы.
- После добавления атрибута его можно увидеть в innerHTML элемента.
- Коллекция attributes содержит все атрибуты в виде объектов со свойствами name и value .
Когда полезен доступ к атрибутам?
Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех стандартных атрибутов.
Например, свойства тега ‘A’ описаны в спецификации DOM: HTMLAnchorElement.
Например, у него есть свойство "href" . Кроме того, он имеет "id" и другие свойства, общие для всех элементов, которые описаны в спецификации в HTMLElement.
Все стандартные свойства DOM синхронизируются с атрибутами, однако не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML, то есть атрибут.
Рассмотрим несколько примеров.
Ссылка «как есть» из атрибута href
Синхронизация не гарантирует одинакового значения в атрибуте и свойстве.
Для примера, посмотрим, что произойдёт с атрибутом "href" при изменении свойства:
Это происходит потому, что атрибут может быть любым, а свойство href , в соответствии со спецификацией W3C, должно быть полной ссылкой.
Стало быть, если мы хотим именно то, что в HTML, то нужно обращаться через атрибут.
Кстати, есть и другие атрибуты, которые не копируются в точности. Например, DOM-свойство input.checked имеет логическое значение true/false , а HTML-атрибут checked – любое строковое, важно лишь его наличие.
Работа с checked через атрибут и свойство:
Исходное значение value
Изменение некоторых свойств обновляет атрибут. Но это скорее исключение, чем правило.
Чаще синхронизация – односторонняя: свойство зависит от атрибута, но не наоборот.
Например, при изменении свойства input.value атрибут input.getAttribute(‘value’) не меняется:
То есть, изменение DOM-свойства value на атрибут не влияет, он остаётся таким же.
А вот изменение атрибута обновляет свойство:
Эту особенность можно красиво использовать.
Получается, что атрибут input.getAttribute(‘value’) хранит оригинальное (исходное) значение даже после того, как пользователь заполнил поле и свойство изменилось.
Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения.
Классы в виде строки: className
Атрибуту "class" соответствует свойство className .
Так как слово "class" является зарезервированным словом в JavaScript, то при проектировании DOM решили, что соответствующее свойство будет называться className .
Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту for ( <label for=". "> ) соответствует свойство с названием htmlFor .
Классы в виде объекта: classList
Атрибут class – уникален. Ему соответствует аж целых два свойства!
Работать с классами как со строкой неудобно. Поэтому, кроме className , в современных браузерах есть свойство classList .
Свойство classList – это объект для работы с классами.
Оно поддерживается в IE начиная с IE10, но его можно эмулировать в IE8+, подключив мини-библиотеку classList.js.
- elem.classList.contains("class") – возвращает true/false , в зависимости от того, есть ли у элемента класс class .
- elem.classList.add/remove("class") – добавляет/удаляет класс class
- elem.classList.toggle("class") – если класса class нет, добавляет его, если есть – удаляет.
Кроме того, можно перебрать классы через for , так как classList – это псевдо-массив.
Нестандартные атрибуты
У каждого элемента есть некоторый набор стандартных свойств, например для <a> это будут href , name , а для <img> это будут src , alt , и так далее.
Точный набор свойств описан в стандарте, обычно мы более-менее представляем, если пользуемся HTML, какие свойства могут быть, а какие – нет.
Для нестандартных атрибутов DOM-свойство не создаётся.
Свойство является стандартным, только если оно описано в стандарте именно для этого элемента.
То есть, если назначить элементу <img> атрибут href , то свойство img.href от этого не появится. Как, впрочем, и если назначить ссылке <a> атрибут alt :
Нестандартные атрибуты иногда используют для CSS.
В примере ниже для показа «состояния заказа» используется атрибут order-state :
Почему именно атрибут? Разве нельзя было сделать классы .order-state-new , .order-state-pending , order-state-canceled ?
Конечно можно, но манипулировать атрибутом из JavaScript гораздо проще.
Например, если нужно отменить заказ, неважно в каком он состоянии сейчас – это сделает код:
Для классов – нужно знать, какой класс у заказа сейчас. И тогда мы можем снять старый класс, и поставить новый:
…То есть, требуется больше исходной информации и надо написать больше букв. Это менее удобно.
Проще говоря, значение атрибута – произвольная строка, значение класса – это «есть» или «нет», поэтому естественно, что атрибуты «мощнее» и бывают удобнее классов как в JS так и в CSS.
Свойство dataset, data-атрибуты
С помощью нестандартных атрибутов можно привязать к элементу данные, которые будут доступны в JavaScript.
Как правило, это делается при помощи атрибутов с названиями, начинающимися на data- , например:
Стандарт HTML5 специально разрешает атрибуты data-* и резервирует их для пользовательских данных.
При этом во всех браузерах, кроме IE10-, к таким атрибутам можно обратиться не только как к атрибутам, но и как к свойствам, при помощи специального свойства dataset :
Обратим внимание – название data-user-location трансформировалось в dataset.userLocation . Дефис превращается в большую букву.
Полифил для атрибута hidden
Для старых браузеров современные атрибуты иногда нуждаются в полифиле. Как правило, такой полифил включает в себя не только JavaScript, но и CSS.
Этот атрибут должен прятать элемент, действие весьма простое, для его поддержки в HTML достаточно такого CSS:
Если запустить в IE11- пример выше, то <div hidden> будет скрыт, а вот последний div , которому поставили свойство hidden в JavaScript – по-прежнему виден.
Это потому что CSS «не видит» присвоенное свойство, нужно синхронизировать его в атрибут.
Вот так – уже работает:
«Особенности» IE8
Если вам нужна поддержка этих версий IE – есть пара нюансов.
Во-первых, версии IE8- синхронизируют все свойства и атрибуты, а не только стандартные:
При этом даже тип данных не меняется. Атрибут не становится строкой, как ему положено.
Ещё одна некорректность IE8-: для изменения класса нужно использовать именно свойство className , вызов setAttribute(‘class’, . ) не сработает.
Вывод из этого довольно прост – чтобы не иметь проблем в IE8, нужно использовать всегда только свойства, кроме тех ситуаций, когда нужны именно атрибуты. Впрочем, это в любом случае хорошая практика.
Итого
- Атрибуты – это то, что написано в HTML.
- Свойство – это то, что находится внутри DOM-объекта.
Таблица сравнений для атрибутов и свойств:
Свойства | Атрибуты |
---|---|
Любое значение | Строка |
Названия регистрозависимы | Не чувствительны к регистру |
Не видны в innerHTML | Видны в innerHTML |
Синхронизация между атрибутами и свойствами:
- Стандартные свойства и атрибуты синхронизируются: установка атрибута автоматически ставит свойство DOM. Некоторые свойства синхронизируются в обе стороны.
- Бывает так, что свойство не совсем соответствует атрибуту. Например, «логические» свойства вроде checked , selected всегда имеют значение true/false , а в атрибут можно записать произвольную строку.Выше мы видели другие примеры на эту тему, например href .
- Нестандартный атрибут (если забыть глюки старых IE) никогда не попадёт в свойство, так что для кросс-браузерного доступа к нему нужно обязательно использовать getAttribute .
- Атрибуты, название которых начинается с data- , можно прочитать через dataset . Эта возможность не поддерживается IE10-.
Для того, чтобы избежать проблем со старыми IE, а также для более короткого и понятного кода старайтесь везде использовать свойства, а атрибуты – только там, где это действительно нужно.
А действительно нужны атрибуты очень редко – лишь в следующих трёх случаях:
- Когда нужно кросс-браузерно получить нестандартный HTML-атрибут.
- Когда нужно получить «оригинальное значение» стандартного HTML-атрибута, например, <input value=". "> .
- Когда нужно получить список всех атрибутов, включая пользовательские. Для этого используется коллекция attributes .
Если вы хотите использовать собственные атрибуты в HTML, то помните, что атрибуты с именем, начинающимся на data- валидны в HTML5 и современные браузеры поддерживают доступ к ним через свойство dataset .
How to add/update an attribute to an HTML element using JavaScript?
I’m trying to find a way that will add / update attribute using JavaScript. I know I can do it with setAttribute() function but that doesn’t work in IE.
4 Answers 4
You can read here about the behaviour of attributes in many different browsers, including IE.
element.setAttribute() should do the trick, even in IE. Did you try it? If it doesn’t work, then maybe element.attributeName = ‘value’ might work.
What seems easy is actually tricky if you want to be completely compatible.
Let’s say you have an id of ‘div1’ to add. These will all work except the last in IE 5.5 (which is ancient history at this point but still is XP’s default with no updates).
But there are contingencies, of course. Will not work in IE prior to 8: e.attributes[‘style’] Will not error but won’t actually set the class, it must be className: e[‘class’] .
However, if you’re using attributes then this WILL work: e.attributes[‘class’]
In summary, think of attributes as literal and object-oriented.
In literal, you just want it to spit out x=’y’ and not think about it. This is what attributes, setAttribute, createAttribute is for (except for IE’s style exception). But because these are really objects things can get confused.
Since you are going to the trouble of properly creating a DOM element instead of jQuery innerHTML slop, I would treat it like one and stick with the e.className = ‘fooClass’ and e.id = ‘fooID’. This is a design preference, but in this instance trying to treat is as anything other than an object works against you.
It will never backfire on you like the other methods might, just be aware of class being className and style being an object so it’s style.width not style=»width:50px». Also remember tagName but this is already set by createElement so you shouldn’t need to worry about it.
This was longer than I wanted, but CSS manipulation in JS is tricky business.