Введение

В предыдущем руководстве данной серии, «Внесение изменений в DOM», мы рассказали о том, как создать, вставить и удалить элементы в объектной модели документов (DOM) с помощью встроенных методов. Благодаря повышению вашего уровня владения манипуляциями с DOM, вы сможете более эффективно использовать интерактивные возможности JavaScript и изменять веб-элементы.

В этом руководстве мы узнаем, как вносить дальнейшие изменения в DOM, меняя стили, классы и другие атрибуты узлов HTML-элементов. Это позволит вам получить более полное представление о том, как манипулировать основными элементами в DOM.

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

До недавнего времени популярная JavaScript-библиотека jQuery чаще всего использовалась для выбора и изменения элементов в DOM. jQuery упрощал процесс выбора одного или нескольких элементов и внесения изменений для всех этих элементов одновременно. В статье «Доступ к элементам в DOM» мы описали методы DOM для захвата и работы с узлами в ванильном JavaScript.

Напоминаем, что document.querySelector() и document.getElementById() — это методы, которые используются для доступа к отдельному элементу. Используя div с атрибутом id в примере ниже, мы так или иначе можем получить доступ к этому элементу.

<div id="demo-id">Demo ID</div>

Метод querySelector()​​​ обладает большей надежностью, поскольку с его помощью можно выбрать элемент на странице по любому типу селектора.

// Both methods will return a single element
const demoId = document.querySelector('#demo-id');

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

// Change the text of one element
demoId.textContent = 'Demo ID text updated.';

Однако при получении доступа к нескольким элементам с общим селектором, например, к какому-то конкретному классу, мы вынуждены проходить по всем элементам в списке. В коде ниже мы имеем два элемента div с общим значением класса.

<div class="demo-class">Demo Class 1</div>
<div class="demo-class">Demo Class 2</div>

Мы будем использовать querySelectorAll() для захвата всех элементов с примененным атрибутом demo-class и forEach() для прохождения по ним и внесения изменений. Также возможно доступ к определенному элементу с помощью querySelectorAll() таким же образом, как и к массиву, т.е. с помощью квадратных скобок.

// Get a NodeList of all .demo elements
const demoClasses = document.querySelectorAll('.demo-class');

// Change the text of multiple elements with a loop
demoClasses.forEach(element => {
  element.textContent = 'All demo classes updated.';
});

// Access the first element in the NodeList
demoClasses[0];

Это одно из самых важных отличий, о которых необходимо помнить при переходе с jQuery на ванильный JavaScript. Многие примеры изменения элементов не будут объяснять процесс применения этих методов и свойств для нескольких элементов.

Свойства и методы в этой статье часто будут сопровождать слушателей событий для ответа на клики, наведения или прочие триггеры.

Примечание. Методы getElementsByClassName() и getElementsByTagName() будут возвращать коллекции HTML, которые не имеют доступа к методу forEach(), в отличие от querySelectorAll(). В этих случаях вам нужно будет использовать стандартный цикл for для прохождения по коллекции.

Изменение атрибутов

Атрибуты — это значения, которые содержат дополнительную информацию об элементах HTML. Обычно они идут в паре название/значение и могут быть обязательными в зависимости от элемента.

Среди самых распространенных атрибутов HTML необходимо отметить атрибут src тега img, href для тега a, class, id и style. Полный список атрибутов HTML см. в списке атрибутов в Mozilla Developer Network. Пользовательские элементы, которые не являются частью стандарта HTML, будут сопровождаться префиксом data-.

В JavaScript есть четыре метода для изменения атрибутов элементов:

Метод Описание Пример
hasAttribute() Возвращает true или false element.hasAttribute('href');
getAttribute() Возвращает значение определенного атрибута или null element.getAttribute('href');
setAttribute() Добавляет или обновляет заданный атрибут element.setAttribute('href', 'index.html');
removeAttribute() Удаляет атрибут элемента element.removeAttribute('href');

Давайте создадим новый файл HTML с тегом img с одним атрибутом. Мы привяжем открытое изображение через URL, но вы можете использовать другое локальное изображение, если вы работаете оффлайн.

attributes.html
<!DOCTYPE html>
<html lang="en">
<body>

    <img src="https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png">

</body>

</html>

При загрузке указанного выше файла HTML в современном веб-браузере и открытии консоли разработчика, вы должны получить примерно следующий вывод:

Первый рендеринг classes.html

Теперь мы можем протестировать все методы атрибутов на ходу.

// Assign image element
const img = document.querySelector('img');

img.hasAttribute('src');                // returns true
img.getAttribute('src');                // returns "...shark.png"
img.removeAttribute('src');             // remove the src attribute and value

К этому моменту вы удалите атрибут src и значение, связанное с тегом img, но вы можете сбросить этот атрибут и присвоить значение другому изображению с помощью img.setAttribute():

img.setAttribute('src', 'https://js-tutorials.nyc3.digitaloceanspaces.com/octopus.png');

Второй рендеринг classes.html

Наконец, мы можем изменить атрибут напрямую, присвоив новое значение атрибуту в качестве свойства элемента, установив src обратно для файла shark.png.

img.src = 'https://js-tutorials.nyc3.digitaloceanspaces.com/shark.png';

Любой атрибут можно изменить таким образом, а также с помощью описанных выше методов.

Методы hasAttribute() и getAttribute() обычно используются с условными операторами, а методы setAttribute() и removeAttribute() используются для прямого изменения DOM.

Изменение классов

Атрибут class соответствует селекторам класса CSS. Не путайте с классами ES6, особым типом функции JavaScript.

Классы CSS используются для применения стилей для нескольких элементов, в отличие от идентификаторов, которые могут существовать только один раз на странице. В JavaScript есть свойства className и classList для работы с атрибутом класса.

Метод/Свойство Описание Пример
className Получает или устанавливает значение класса element.className;
classList.add() Добавляет одно или несколько значений класса element.classList.add('active');
classList.toggle() Включает или отключает класс element.classList.toggle('active');
classList.contains() Проверяет, существует ли значение класса element.classList.contains('active');
classList.replace() Заменяет существующее значение класса на новое значение класса element.classList.replace('old', 'new');
classList.remove() Удаляет значение класса element.classList.remove('active');

Мы создадим другой файл HTML для работы с методами класса, с двумя элементами и несколькими классами.

classes.html
<!DOCTYPE html>
<html lang="en">

<style>
    body {
        max-width: 600px;
        margin: 0 auto;
        font-family: sans-serif;
    }
    .active {
        border: 2px solid blue;
    }

    .warning {
        border: 2px solid red;
    }

    .hidden {
        display: none;
    }

    div {
        border: 2px dashed lightgray;
        padding: 15px;
        margin: 5px;
    }
</style>

<body>

    <div>Div 1</div>
    <div class="active">Div 2</div>

</body>

</html>

При открытии файла classes.html в браузере вы должны получить примерно следующий результат:

Первый рендеринг classes.html

Свойство className было введено для предотвращения конфликтов с ключевым словом class в JavaScript и другими языками, которые имеют доступ к DOM. Вы можете использовать className для присвоения значения напрямую в классе.

// Select the first div
const div = document.querySelector('div');

// Assign the warning class to the first div
div.className = 'warning';

Мы присвоили класс warning, определенный в значениях CSS в classes.html, для первого div. Вывод должен выглядеть следующим образом:

Второй рендеринг classes.html

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

Другой способ изменения классов — это свойство classList, которое имеет несколько полезных методов. Эти методы аналогичны методами addClass, removeClass и toggleClass в jQuery.

// Select the second div by class name
const activeDiv = document.querySelector('.active');

activeDiv.classList.add('hidden');                // Add the hidden class
activeDiv.classList.remove('hidden');             // Remove the hidden class
activeDiv.classList.toggle('hidden');             // Switch between hidden true and false
activeDiv.classList.replace('active', 'warning'); // Replace active class with warning class

После использования описанных выше методов ваша веб-страница будет выглядеть следующим образом:

Первый рендеринг classes.html

В отличие от примера с className, использование classList.add() будет добавлять новый класс в список существующих классов. Также вы можете добавить несколько в виде разделенной запятыми строки. Также вы можете использовать setAttribute для изменения класса элемента.

Изменение стилей

Свойство style отражает вложенные стили элемента HTML. Часто стили будут применяться к элементам через таблицу стилей, как мы делали ранее в этой статье, но иногда нам будет нужно добавить или изменить вложенный стиль напрямую.

Мы создадим небольшой пример для демонстрации редактирования стилей с помощью JavaScript. Ниже представлен новый файл HTML с блоком div, который имеет вложенные стили, применяемые для отображения квадрата.

styles.html
<!DOCTYPE html>
<html lang="en">

<body>

    <div style="height: 100px;
                width: 100px;
                border: 2px solid black;">Div</div>

</body>

</html>

После открытия в браузере, styles.html будет выглядеть примерно следующим образом:

Первый рендеринг styles.html

Один из вариантов редактирования стилей подразумевает использование setAttribute().

// Select div
const div = document.querySelector('div');

// Apply style to div
div.setAttribute('style', 'text-align: center');

Однако при этом будут удалены все существующие вложенные стили для элемента. Поскольку это вряд ли является желаемым результатом, рекомендуется использовать напрямую атрибут style

div.style.height = '100px';
div.style.width = '100px';
div.style.border = '2px solid black';

Свойства CSS записаны в кебаб-регистре, т.е. в нижнем регистре, разделенные тире. Важно отметить, что свойства CSS в кебаб-регистре не могут использоваться для свойства стиля JavaScript. Вместо этого они будут заменены на их эквивалент в верблюжьем регистре, когда первое слово имеет нижний регистр, а все последующие слова начинаются с заглавной буквы. Иными словами, вместо text-align мы будем использовать textAlign для свойства стиля JavaScript.

// Make div into a circle and vertically center the text
div.style.borderRadius = '50%';
div.style.display = 'flex';
div.style.justifyContent = 'center';
div.style.alignItems = 'center';

После внесения описанных выше изменений стиля итоговый рендеринг styles.html будет представлять собой круг:

Итоговый рендеринг styles.html

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

Заключение

HTML-элементы часто содержат дополнительную информацию в форме атрибутов. Активы могут состоять из пар название/значение, а самыми распространенными атрибутами являются атрибуты class и style.

В этом руководстве мы узнали, как получить доступ, изменять и удалять атрибуты для элемента HTML в DOM с помощью простого JavaScript. Также мы научились добавлять, удалять, переключать и заменять классы CSS для элемента и редактировать вложенные стили CSS. Для получения дополнительной информации ознакомьтесь с документацией по атрибутам в Mozilla Developer Network.

0 Comments

Creative Commons License