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

Немного базы

Атрибуты это пары ключ значения которые находятся прямо в дескрипторе HTML тега:

<div class="someClass"></div> 

Множество атрибутов входят в состав спецификации HTML5: какие-то просто содержат метаданные элемента (class, name, id), от каких-то зависит отображение элемента в браузере (type, checked). Но так как HTML, это всего лишь расширение спецификации языка XML, то никто нам не мешает нам придумать и внедрить свой атрибут:

<div class="someClass" my-new-attribut="Hello word"></div>

После добавления атрибута my-new-attribut в код, всё будет по-прежнему корректно отображается. Компьютер не взорвётся и даже браузера не зависнет. Правда и толку от этого новшества пока не видно. Но это только пока!

Методы для работы с атрибутами в JavaScript

Для работы с атрибутами, в JS существует несколько универсальных методов:

  • getAttribute() - получает значение атрибута по его имени;

  • setAttribute() - устанавливает атрибут с указанным именем и значением;

  • hasAttribute() - проверяет наличие атрибута с указанным именем;

  • removeAttribute() - удаляет указанный атрибут.

Все примеры кода на JavaScript будут работать с вот такой вот простенькой HTMLькой:

<!DOCTYPE html>  
<html lang="ru">  
<head>  
    <meta charset="UTF-8">  
    <title>HTML атрибуты и JavaScript</title>  
</head>  
<body>  
<div class="someClass main-block" name="block">  
    <form action="" data-action-url="some/url/">  
        <input type="text" name="user-name" value="Вася">  
    </form></div>  
<script src="js/script.js"></script>  
</body>  
</html>
const elem = document.querySelector('.someClass')  
  
elem.setAttribute('name', 'block') // Устанавливает атрибут name со значением block
elem.getAttribute('name') // Возвращает значение block
elem.hasAttribute('name') // Возвращает true, так как атрибут name существует
elem.removeAttribute('name') // Удаляет атрибут name

Атрибуты как свойства HTMLElement

Со стандартными атрибутами из спецификации HTML, всё гораздо проще. Они доступны для чтения и записи как свойства объекта HTMLElement, который можно получить при помощи селекторов. Стоит учитывать что в данном объекте имена свойств, могут отличаться от имён самих атрибутов. Например, у тега поля input, имеется стандартный атрибут value, которых содержит значение введённое пользователем. В объекте HTMLElement, данный атрибут будет доступен через свойство defaultValue. Отличие в имени свойства и атрибута, позволяют избежать конфликтов с синтаксисом JavaScript.

Свойств объекта HTMLElement, в отличие от самих атрибутов, чувствительны к регистру. В объекте имена свойств всегда будут в нижнем регистре, а если имя атрибута состоит из нескольких слов, то для их написания используется нотация camelCase, за исключение свойств событий, которые записываются в нижнем регистре (onclick). Если имя атрибута совпадает с зарезервированным словом в JavaScript, то оно снабжается префиксом html, например атрибут for, в HTMLElement, доступен под именем htmlFor. Исключением из данного правила является атрибут class, доступный через свойство className.

const elem = document.querySelector('input')  
  
elem.type // text
elem.defaultValue // Вася
elem.name // user-name

Чаще всего, атрибут будет иметь строковое значение. Но если у атрибута предполагается булево значение (defaultChecked, maxLength), то значение свойства объекта HTMLElement, также будет булевым типом. Значение атрибутов, задающих обработчики пользовательских событий (onclick, onchange и т.д.) событий всегда равно null.

Через объект HTMLElement, никак нельзя удалить атрибут у элемента (оператор delete, не сработает), единственный способ сделать это метод removeAttribute().

Атрибут class

Работа с атрибутом class в JavaScript несколько выделяется. В свойстве className, объекта Element, все классы хранятся в виде обычной строки. Манипулировать классами элементов, работая с обычной строкой было бы крайне муторно, поэтому для этих целей в JS был добавлен отдельный интерфейс, хранящийся в свойстве classList. Он состоит из методов:

  • add() - добавляет новый класс элементу;

  • remove() - удаляет указанный класс у элемента;

  • contains() - проверяет наличие класса у элемента;

  • toggle() - добавляет класс элементу если его нет, удаляет его если он есть.

const elem = document.querySelector('.someClass')  
 
elem.classList.add('new-class') // Добавляет класс new-class элементу
elem.classList.contains('someClass') // Возвращает true
elem.classList.toggle('someClass') // Удаляет someClass, возвращает false
elem.classList.toggle('someClass') // Добавляем someClass, возвращает true
elem.classList.remove('new-class') // Удаляет класс new-class у элемента

В самом свойстве classList, хранится объект DOMTokenList. Он является итерируемым, а значит его можно перебрать в цикле.

const elem = document.querySelector('.someClass')  
  
сssClasses = elem.classList  
  
for(let i = 0; сssClasses.length > i; i++) {  
    // Получаем классы через сssClasses[i]
}

Dataset

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

Важность этой фичи сложно переоценить, ведь в JavaScrip, для работы с данными атрибутами, реализован специальный интерфейс. Получить доступ к таким атрибутам имеющим префикс data-, можно через свойство dataset объекта Element. Там они хранятся в виде объекта со свойствами, имена которых идентичны именам атрибутов, но уже без префикса data-. Например, значение атрибута data-action-url, будет доступно в JS через свойство dataset.actionUrl:

const form = document.querySelector('form')  
  
console.log(form.dataset.actionUrl) // Будет равно: Some data

Вывод

JavaScript имеет обширный и удобный интерфейс для работы с атрибутами HTML элементов, который по традиции заведённой в JS избыточен. Знать что атрибуты доступны, в виде свойств объекта HTMLElement нужно, но использования этой методики в практическом коде, лучше избегать, дабы его не усложнять. Также не стоит использовать работу с объектом из свойства classList, в цикле. Прочесть об этом полезно, использовать в деле нет! Применяя из многообразия синтаксиса JavaScript, наиболее универсальные интерфейсы, фронтендеры могут упростить жизнь друг, другу.

Комментарии (18)


  1. space2pacman
    05.02.2025 09:43

    Зачем вы это тащите сюда? Это уже давно есть на https://learn.javascript.ru/


    1. JastaFly Автор
      05.02.2025 09:43

      А это как-то запрещено? Львиная доля того что публикуется на хабре это рерайты и переводы с буржуйского


      1. space2pacman
        05.02.2025 09:43

        А это как-то запрещено?

        Нет, как и бросать окурки из окна автомобиля. Давайте гадить везде. Завтра опубликую статью в чем разница var и let. А вы в 100-ый раз распишите что такое this в JS.

        А вы отталкиваетесь только от запретов? Почему нельзя ссылаться на здравый смысл и желанием заполнять хабр полезным и уникальным материалом?


        1. JastaFly Автор
          05.02.2025 09:43

          как и бросать окурки из окна автомобиля

          Ну вообще-то запрещено. Не стоит всегда мыслить категориями родного хутора

          Завтра опубликую статью в чем разница var и let

          Ну кстати в этой теме есть куда копнуть и примитивной она может казаться, только чуваку прошедшему курс Гоши Дударя по JS

          А вы в 100-ый раз распишите что такое this в JS

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

          полезным и уникальным материалом

          А кто будет пользу и уникальность оценивать? Вы? Ну так всё тут всё субъективно. То что кажется Вам элементарным, для новичка будет открытием, а то что Вам кажется сложным и интересным, более шаристому челу покажется детским садом. Уровень данной статьи, я оценил как простой. Международных наград и премий за неё не требую. Это статься для фронтенд неофитов)

          Уникальность, тут опять-же, много из того что тут пишется и без того есть в документации, книгах, забугорных статьях. Как будем решать что действительно уникально, а что нет? Да и блин, это просто соцсеть для гиков, а не научный журнал с полувековой историей, ТИЦем, рецензиями, блекджеком и шлюхами. Относитесь к местному контенту проще что-ли)


          1. space2pacman
            05.02.2025 09:43

            Ну кстати в этой теме есть куда копнуть

            Что там копать?

            Однажды и эту тему освещу однозначно

            Зачем? Уже все давно описали. Что вы нового добавите?

            А кто будет пользу и уникальность оценивать? Вы? Ну так всё тут всё субъективно

            Достаточно загуглить то о чем вы пишете и как гугл так и хабр выдаст сотни материалов. Перед тем как публиковать убедитесь, что информации по вашему материалу мало.

            Вам элементарным, для новичка будет открытием

            Про какое открытие речь если гугл и хабр завален подобным материалом?


            1. JastaFly Автор
              05.02.2025 09:43

              Что там копать?

              Да много чего. Для воспитанника Гоши Дударя там разница только в том что let, новее и предпочтительнее. Ну и дай бог он ещё про разницу областей видимости знает. Для JS гуру, там куча неочевидных нюансов, let и var ведут себя в разных контекстах по разному. По разному затеняются сами и затеняют друг друга. Все эти особенности могут привести к очень неочевидным и сложно отлавливаемым сайдам

              Что вы нового добавите?

              Свой взгляд на использование. Что в этом плохого?

              Достаточно загуглить то о чем вы пишете и как гугл так и хабр выдаст сотни материалов

              Бесспорно выдаст, только вот моя статья будет на 2-й позиции в выдаче:

              Перед тем как публиковать убедитесь, что информации по вашему материалу мало.

              В литература есть всего 12 сюжетов. Хорошо что Вы разраб, а не драматург)

              Про какое открытие речь

              Вам знакомо понятие контекста? Я тут чётко его обозначил как раз, как открытие для новичка, а не открытие в смысле: "О боже это гениально! 2 нобелевских премии этому парню". Ну вот прикиньте для кого-то это может быть открытием с большой буквы О! Я на практике встречал код где чуваки вместо атрибутов data, запихивали служебную инфу с бека в обычные теги и скрывали их в CSS. Встречал код в котором с классами CSS, работали как с обычными строками, деструктурируя их через регулярки. Не стоит думать что, то что очевидно Вам, очевидно всем)


              1. space2pacman
                05.02.2025 09:43

                Кто такой этот ваш Гоша Дударь?

                let и var ведут себя в разных контекстах по разному

                Какие контексты для операторов присвоения?

                Все эти особенности могут привести к очень неочевидным и сложно отлавливаемым сайдам

                К чему?

                Свой взгляд на использование. Что в этом плохого?

                Какой взгляд?

                Есть гайка. Как ее не крути на болт результат будет одинаковый.

                Взаимодействие микро сервисов может быть разное. Разработка high-load систем. Но использование атрибутов преподносится как что-то необычное со своим взглядом?

                В литература есть всего 12 сюжетов. Хорошо что Вы разраб, а не драматург)

                Некорректное сравнение. Вы не рассказываете про построение архитектуры приложения. Если вернутся к аналогии на литературу то ваша статья описывает правила русского языка. Как составлять повествовательные предложения. Только этот материал уже есть в сети. И у учебниках русского языка аж с советских времен.

                Не стоит думать что, то что очевидно Вам, очевидно всем)

                Вопрос не про очевидность а про, что практически слово в слово такой материал уже есть во всех учебниках и онлайн библиотеках на подобии https://learn.javascript.ru/ Вы просто берете и перепечатываете.


              1. space2pacman
                05.02.2025 09:43

                Относитесь к местному контенту проще что-ли)

                Так я и предлагаю. Давайте загадим хабр вместе. Я про let и var пишу а вы про this. Договорились?


              1. space2pacman
                05.02.2025 09:43

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

                Соедините готовый материал с чем-то новым. Статья будет интереснее.


                1. JastaFly Автор
                  05.02.2025 09:43

                  Кто такой этот ваш Гоша Дударь?

                  Легенда!

                  Какие контексты для операторов присвоения?

                  Ну видимо для Вас это действительно так, просто штука объявляющая переменные. Для людей искушённых в JS у них разное поведение в блочном и глобальном контексте, разная реакция на попытки переопределения и ещё куча неожиданностей которая может возникнуть вот в такой вот базовой для любого языка фиче. Для начала задумайтесь, а с чего операторов присваивания тут вообще 2? Часто встречаете такое в других языка?!

                  Какой взгляд?

                  Пока не знаю. Бумага для моей статьи по this, ещё в лесу растёт. Просто вижу что Вам эта тема, кажется чем-то чем-то элементарным, какое-то там слово this, штука в классе чтобы вызвать что-то ещё из класса. А там тоже всё не так просто)

                  И у учебниках русского языка аж с советских времен

                  Замете правила не меняются десятилетиями, а их носители обновляются регулярно

                  Взаимодействие микро сервисов может быть разное. Разработка high-load систем

                  Это субъективщина. Вам может это и будет казаться крутым. Матёрого сеньора, мало чем удивит очередная статья, о том как реббита прикрутить к своим говносервисам

                  Договорились?

                  Вай нот)

                  Примеры веб приложений где бы это могло быть полезно, игры и т.д.

                  Годная мысль! Возможно попробую прикрутить пример на код пене в следующий раз


                  1. space2pacman
                    05.02.2025 09:43

                    Для начала задумайтесь, а с чего операторов присваивания тут вообще 2? Часто встречаете такое в других языка?!

                    Доброе утро

                    https://learn.javascript.ru/variables

                    Вникайте.

                    Просто вижу что Вам эта тема, кажется чем-то чем-то элементарным, какое-то там слово this

                    Вопрос не про сложно / легко. А про то, что этот материал уже давно расписан.

                    Бесконечно можно описывать архитектурные подходы.

                    А не материал про то как накручивать гайку на болт. Один раз написали накручивать по часовой, выкручивать против часовой и все.

                    Материал который уже есть:

                    Гайка на болт накручивается по часовой стрелке

                    Ваша статья:

                    Болт на гайку по стрелке часовой крутить надо и она будет накручиваться.

                    От этого и вопрос: Зачем?


                    1. JastaFly Автор
                      05.02.2025 09:43

                      Вникайте

                      Да что Вы мне этим тычите. Мой вопрос был именно к Вам, а не к сухой документации и носит концептуально прикладной характер. Зачем разрабам языка понадобилось 2 ключевых слова, для объявления переменных?! Много Вы знаете языков где ещё так?!

                      Бесконечно можно описывать архитектурные подходы

                      Опять же субъективщина. По архитектуре всё тоже писано, переписано уже по 10 раз. Просто конкретно Вам, на конкретно Вашем уровне это кажется крутым. А кому-то нет. А кому-то интересно будет и статью по HTML прочесть. Устал уже в который раз писать, столь примитивную мысль


                      1. space2pacman
                        05.02.2025 09:43

                        Да что Вы мне этим тычите. Мой вопрос был именно к Вам, а не к сухой документации и носит концептуально прикладной характер. Зачем разрабам языка понадобилось 2 ключевых слова, для объявления переменных?! Много Вы знаете языков где ещё так?!

                        Потому что там все расписано: что, зачем и почему. К чему тут философствовать?

                        Ответ уже есть почему два оператора. А точнее три. А вы хотите рассуждения в обход книг и документации чтобы что?


                      1. space2pacman
                        05.02.2025 09:43

                        Никому два оператора не понадобилось. Вы о чем?. Сначала появился var и спустя много лет появился let

                        И удалять никто не будет так как потеряется обратная совместимость.


                      1. JastaFly Автор
                        05.02.2025 09:43

                         К чему тут философствовать

                        А к тому что именно знание подобных нюансов отличают ремесленника формошлёпа, которому что молоток, что кувалда, один фиг, от мастера с чёрным поясном по компьютер сайнс

                        Никому два оператора не понадобилось

                        Тогда логичный вопрос, а зачем тогда они понадобились разрабам JS? Они что особенные? Ну вот не было бы let и что тогда? Вы бы разницу заметили?

                        Вы о чем?

                        О том что вы даже не понимая разницы между var и let, критикуете статью затрагивающую более комплексный механизм языка :D


                      1. space2pacman
                        05.02.2025 09:43

                        А к тому что именно знание подобных нюансов отличают ремесленника формошлёпа, которому что молоток, что кувалда, один фиг, от мастера с чёрным поясном по компьютер сайнс

                        Знания. А не философствование. Вместо прочтения статьи и моих ответов. Вы почему-то до сих пор мне задаете вопрос про два оператора. Я вам дал избыточный ответ. Почему вы продолжаете спрашивать вместо поглощение знаний?

                        Тогда логичный вопрос, а зачем тогда они понадобились разрабам JS? Они что особенные? Ну вот не было бы let и что тогда? Вы бы разницу заметили?

                        Вы читаете, что я пишу и скидываю?