Перейти к содержимому

Как обратиться к атрибуту тега через javascript

  • автор:

Работа с атрибутами элементов в JavaScript

В JavaScript существует набор методов для изменения, создания, удаления и проверки существования атрибутов HTML тегов.

  • getAttribute(‘X’) — возвращает значение атрибута с названием ‘X’
  • setAttribute(‘X’, ‘Y’) — устанавливает значение атрибута с названием ‘X’ в значение ‘Y’
  • removeAttribute(‘X’) — удаляет атрибут ‘X’
  • hasAttribute(‘X’) — проверяет наличие атрибута ‘X’
Кликни на меня!
function MyFunc(a)

Если загрузить страницу браузера с таким примером и кликнуть на «Кликни на меня!», то появится всплывающее окно:

В примере использован атрибут, название которого придумано самостоятельно. Но для таких случаев лучше создавать атрибуты с префиксом data-. К примеру, data-mouse.

Используем остальные методы. Попробуем установить значение атрибута «mouse» в «Сыр!» с помощью setAttribute. Для этого напишем следующий код:

Кликни на меня!
function MyFunc(a)

В этом примере мы сначала установили значение атрибута «mouse» в «Сыр!», а затем прочитали его. В итоге получилось всплывающее окно с текстом «Сыр!»: Немного модифицируем предыдущий пример, чтобы продемонстрировать работу removeAttribute на удалении атрибута «mouse».

Кликни на меня!
function MyFunc(a)

Очевидно, что если атрибут будет удалён, то функция getAttribute не сможет ничего вернуть (точнее вернёт отсутствие значение — «null»): Осталось продемонстрировать последний метод hasAttribute, который служит для проверки существования атрибута. Этот метод возвращает логические «true» («правда») или «false» («ложь»). Составим пример, который будет наглядно показывать разницу

Кликни на меня!

При выполнении такого кода мы увидим всплывающее окно с текстом «Атрибут mouse существует!»: Но всплывающего окна с текстом «Атрибут cat существует!» не будет, потому что такого атрибута у элемента нет.

Поиск: getElement*, querySelector*

Свойства навигации по DOM хороши, когда элементы расположены рядом. А что, если нет? Как получить произвольный элемент страницы?

Для этого в DOM есть дополнительные методы поиска.

document.getElementById или просто id

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

Также есть глобальная переменная с именем, указанным в id :

…Но это только если мы не объявили в JavaScript переменную с таким же именем, иначе она будет иметь приоритет:

Пожалуйста, не используйте такие глобальные переменные для доступа к элементам

Это поведение соответствует стандарту, но поддерживается в основном для совместимости, как осколок далёкого прошлого.

Браузер пытается помочь нам, смешивая пространства имён JS и DOM. Это удобно для простых скриптов, которые находятся прямо в HTML, но, вообще говоря, не очень хорошо. Возможны конфликты имён. Кроме того, при чтении JS-кода, не видя HTML, непонятно, откуда берётся переменная.

В этом учебнике мы будем обращаться к элементам по id в примерах для краткости, когда очевидно, откуда берётся элемент.

В реальной жизни лучше использовать document.getElementById .

Значение id должно быть уникальным

Значение id должно быть уникальным. В документе может быть только один элемент с данным id .

Если в документе есть несколько элементов с одинаковым значением id , то поведение методов поиска непредсказуемо. Браузер может вернуть любой из них случайным образом. Поэтому, пожалуйста, придерживайтесь правила сохранения уникальности id .

Только document.getElementById , а не anyElem.getElementById

Метод getElementById можно вызвать только для объекта document . Он осуществляет поиск по id по всему документу.

querySelectorAll

Самый универсальный метод поиска – это elem.querySelectorAll(css) , он возвращает все элементы внутри elem , удовлетворяющие данному CSS-селектору.

Этот метод действительно мощный, потому что можно использовать любой CSS-селектор.

Псевдоклассы тоже работают

Псевдоклассы в CSS-селекторе, в частности :hover и :active , также поддерживаются. Например, document.querySelectorAll(‘:hover’) вернёт коллекцию (в порядке вложенности: от внешнего к внутреннему) из текущих элементов под курсором мыши.

querySelector

Метод elem.querySelector(css) возвращает первый элемент, соответствующий данному CSS-селектору.

Иначе говоря, результат такой же, как при вызове elem.querySelectorAll(css)[0] , но он сначала найдёт все элементы, а потом возьмёт первый, в то время как elem.querySelector найдёт только первый и остановится. Это быстрее, кроме того, его короче писать.

matches

Предыдущие методы искали по DOM.

Метод elem.matches(css) ничего не ищет, а проверяет, удовлетворяет ли elem CSS-селектору, и возвращает true или false .

Этот метод удобен, когда мы перебираем элементы (например, в массиве или в чём-то подобном) и пытаемся выбрать те из них, которые нас интересуют.

. .  

closest

Предки элемента – родитель, родитель родителя, его родитель и так далее. Вместе они образуют цепочку иерархии от элемента до вершины.

Метод elem.closest(css) ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск.

Другими словами, метод closest поднимается вверх от элемента и проверяет каждого из родителей. Если он соответствует селектору, поиск прекращается. Метод возвращает либо предка, либо null , если такой элемент не найден.

getElementsBy*

Существуют также другие методы поиска элементов по тегу, классу и так далее.

На данный момент, они скорее исторические, так как querySelector более чем эффективен.

Здесь мы рассмотрим их для полноты картины, также вы можете встретить их в старом коде.

  • elem.getElementsByTagName(tag) ищет элементы с данным тегом и возвращает их коллекцию. Передав «*» вместо тега, можно получить всех потомков.
  • elem.getElementsByClassName(className) возвращает элементы, которые имеют данный CSS-класс.
  • document.getElementsByName(name) возвращает элементы с заданным атрибутом name . Очень редко используется.
// получить все элементы div в документе let divs = document.getElementsByTagName('div');

Давайте найдём все input в таблице:

 
Ваш возраст:
let inputs = table.getElementsByTagName('input'); for (let input of inputs)

Не забываем про букву «s» !

Одна из самых частых ошибок начинающих разработчиков (впрочем, иногда и не только) – это забыть букву «s» . То есть пробовать вызывать метод getElementByTagName вместо getElementsByTagName .

Буква «s» отсутствует в названии метода getElementById , так как в данном случае возвращает один элемент. Но getElementsByTagName вернёт список элементов, поэтому «s» обязательна.

Возвращает коллекцию, а не элемент!

Другая распространённая ошибка – написать:

// не работает document.getElementsByTagName('input').value = 5;

Попытка присвоить значение коллекции, а не элементам внутри неё, не сработает.

Нужно перебрать коллекцию в цикле или получить элемент по номеру и уже ему присваивать значение, например, так:

// работает (если есть input) document.getElementsByTagName('input')[0].value = 5;

Ищем элементы с классом .article :

 
Long article

Живые коллекции

Все методы «getElementsBy*» возвращают живую коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.

В приведённом ниже примере есть два скрипта.

  1. Первый создаёт ссылку на коллекцию . На этот момент её длина равна 1 .
  2. Второй скрипт запускается после того, как браузер встречает ещё один , теперь её длина – 2 .
First div
Second div

Напротив, querySelectorAll возвращает статическую коллекцию. Это похоже на фиксированный массив элементов.

Если мы будем использовать его в примере выше, то оба скрипта вернут длину коллекции, равную 1 :

First div
Second div

Теперь мы легко видим разницу. Длина статической коллекции не изменилась после появления нового div в документе.

Итого

Есть 6 основных методов поиска элементов в DOM:

Метод Ищет по. Ищет внутри элемента? Возвращает живую коллекцию?
querySelector CSS-selector
querySelectorAll CSS-selector
getElementById id
getElementsByName name
getElementsByTagName tag or ‘*’
getElementsByClassName class

Безусловно, наиболее часто используемыми в настоящее время являются методы querySelector и querySelectorAll , но и методы getElement(s)By* могут быть полезны в отдельных случаях, а также встречаются в старом коде.

  • Есть метод elem.matches(css) , который проверяет, удовлетворяет ли элемент CSS-селектору.
  • Метод elem.closest(css) ищет ближайшего по иерархии предка, соответствующему данному CSS-селектору. Сам элемент также включён в поиск.

И, напоследок, давайте упомянем ещё один метод, который проверяет наличие отношений между предком и потомком:

  • elemA.contains(elemB) вернёт true , если elemB находится внутри elemA ( elemB потомок elemA ) или когда elemA==elemB .

Задачи

Поиск элементов

важность: 4

Вот документ с таблицей и формой.

  1. Таблицу с id=»age-table» .
  2. Все элементы label внутри этой таблицы (их три).
  3. Первый td в этой таблице (со словом «Age»).
  4. Форму form с именем name=»search» .
  5. Первый input в этой форме.
  6. Последний input в этой форме.

Откройте страницу table.html в отдельном окне и используйте для этого браузерные инструменты разработчика.

Есть много путей как это сделать.

// 1. Таблица с `id="age-table"`. let table = document.getElementById('age-table') // 2. Все label в этой таблице table.getElementsByTagName('label') // или document.querySelectorAll('#age-table label') // 3. Первый td в этой таблице table.rows[0].cells[0] // или table.getElementsByTagName('td')[0] // или table.querySelector('td') // 4. Форма с name="search" // предполагаем, что есть только один элемент с таким name в документе let form = document.getElementsByName('search')[0] // или, именно форма: document.querySelector('form[name="search"]') // 5. Первый input в этой форме form.getElementsByTagName('input')[0] // или form.querySelector('input') // 6. Последний input в этой форме let inputs = form.querySelectorAll('input') // найти все input inputs[inputs.length-1] // взять последний

Использование data-* атрибутов

HTML5 спроектирован с возможностью расширения данных ассоциированных с каким-либо элементом, но в то же время не обязательно имеющих определённое значение. data-* атрибуты позволяют хранить дополнительную информацию в стандартных элементах HTML, без хаков вроде нестандартных атрибутов, лишних DOM-свойств или Node.setUserData() .

Синтаксис HTML

Синтаксис прост — любой атрибут, чьё имя начинается с data- , является data-* атрибутом. Предположим у нас имеется статья и мы хотим сохранить дополнительную информацию без визуального представления. Для этого можно использовать data -атрибуты:

article id="electriccars" data-columns="3" data-index-number="12314" data-parent="cars"> . article> 

Доступ в JavaScript

Чтение data- атрибутов в JavaScript осуществляется также просто. Для этого можно использовать метод getAttribute() с параметром, равным полному имени атрибута. Но есть и более простой способ, используя объект dataset .

Чтобы получить data -атрибут можно взять свойство объекта dataset с именем, равным части имени атрибута после data- (обратите внимание, что дефисы в имени преобразуются в camelCase).

var article = document.getElementById('electriccars'); article.dataset.columns // "3" article.dataset.indexNumber // "12314" article.dataset.parent // "cars"

Каждое свойство является строкой и может быть прочитано и записано. В приведённом выше примере выполнение кода article.dataset.columns = 5 приведёт к тому, что новое значение атрибута станет равным «5» .

Доступ в CSS

Заметим, что data -атрибуты являются обычными HTML-атрибутами, к которым можно получить доступ в CSS. Например, чтобы показать родительские данные о статье можно использовать генерируемый контент и CSS функцию attr() :

article::before  content: attr(data-parent); > 

Также можно использовать селекторы атрибутов в CSS для изменения стилей в соответствии с данным:

article[data-columns="3"]  width: 400px; > article[data-columns="4"]  width: 600px; > 

Увидеть как это работает можно в примере на JSBin.

Data -атрибуты также могут использоваться для хранения информации, которая постоянно изменяется, например, счёт в игре. Используя CSS селекторы и возможности JavaScript можно создавать некоторые изящные эффекты, без необходимости писать свои функции отображения. Посмотрите скринкаст чтобы увидеть больше примеров использующих сгенерированный контент и переходы на CSS. Пример кода из скринкаста можно также посмотреть на JSBin.

Проблемы

Не храните данные, которые должны быть видимы и доступны в data -атрибутах. Дело в том, что вспомогательная техника (assistive technology) может не получить к ним доступ. В дополнение, поисковые роботы не индексируют данные, содержащиеся в data -атрибутах.

Печально, что всё простое и полезное в этой жизни не достаётся бесплатно. Internet Explorer 11+ поддерживает этот стандарт, но все более ранние версии не поддерживают dataset . Для поддержки IE 10 и более ранних версий получение доступа к data -атрибутам необходимо осуществлять через getAttribute() . Также, производительность чтения data- атрибутов по сравнению с хранением этих данных в хранилище данных JS значительно хуже. Использование dataset ещё медленнее, чем чтение данных с getAttribute() .

Тем не менее, для пользовательских метаданных, связанных с элементами, data- атрибуты являются отличным решением.

Смотрите также

  • This article is adapted from Using data attributes in JavaScript and CSS on hacks.mozilla.org.
  • How to use HTML5 data attributes (Sitepoint)

Работа с атрибутами тегов через свойства элементов

Давайте теперь научимся получать атрибуты тегов. Здесь действует следующее правило: каждому атрибуту тега соответствует одноименное свойство DOM элемента.

Давайте посмотрим на примере. Пусть у нас есть вот такой тег:

Пусть ссылка на этот тег хранится в переменной elem . Тогда свойство elem.id будет хранить текст атрибута id , а свойство elem.type — текст атрибута type .

Давайте сделаем еще и кнопку, по нажатию на которую будут выводиться атрибуты нашего инпута:

Получим ссылки на инпут и кнопку в соответствующие переменные:

let button = document.querySelector(‘#button’); let elem = document.querySelector(‘#elem’);

А теперь по нажатию на кнопку выведем содержимое соответствующих атрибутов:

button.addEventListener(‘click’, function() < alert(elem.id); // выведет 'elem' alert(elem.type); // выведет 'text' >);

Можно не только считывать значения атрибутов, но и менять их значения, изменяя соответствующие свойства DOM элементов. Давайте для примера поменяем значение атрибута type :

button.addEventListener(‘click’, function() < elem.type = 'submit'; // присвоим новое значение атрибуту type >);

Дан следующий инпут:

Дана также кнопка. По нажатию на кнопку выведите на экран содержимое атрибута type указанного выше инпута.

Дан следующий инпут:

Дана также кнопка. По нажатию на кнопку запишите в атрибут type значение submit .

Пусть у вас есть ссылка в виде тега a , кнопка и абзац. По нажатию на кнопку выведите в абзац содержимое атрибута href ссылки.

Пусть у вас есть ссылка и кнопка. По нажатию на кнопку добавьте в конец текста ссылки содержимое ее атрибута href в круглых скобках.

Пусть у вас есть картинка. Разместите ее на странице в помощью тега img . Пусть даны также кнопка и абзац. Сделайте так, чтобы по клику на кнопку в абзац записался путь к картинки из ее атрибута src .

Дана картинка в теге img и кнопка. По нажатию на кнопку в атрибут width запишите значение 300 .

Дана картинка в теге img и кнопка. Пусть в атрибуте width задана некоторая ширина. Сделайте кнопку, по нажатию на которую ширина картинки будет увеличиваться в 2 раза.

Пусть у вас есть две картинки. Сделайте на странице тег img и две кнопки. По нажатию на первую кнопку запишите в атрибут src путь к первой картинке, а по нажатию на вторую — путь ко второй картинке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *