В предыдущей статье об основах 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, наиболее универсальные интерфейсы, фронтендеры могут упростить жизнь друг, другу.
space2pacman
Зачем вы это тащите сюда? Это уже давно есть на https://learn.javascript.ru/
JastaFly Автор
А это как-то запрещено? Львиная доля того что публикуется на хабре это рерайты и переводы с буржуйского
space2pacman
Нет, как и бросать окурки из окна автомобиля. Давайте гадить везде. Завтра опубликую статью в чем разница var и let. А вы в 100-ый раз распишите что такое this в JS.
А вы отталкиваетесь только от запретов? Почему нельзя ссылаться на здравый смысл и желанием заполнять хабр полезным и уникальным материалом?
JastaFly Автор
Ну вообще-то запрещено. Не стоит всегда мыслить категориями родного хутора
Ну кстати в этой теме есть куда копнуть и примитивной она может казаться, только чуваку прошедшему курс Гоши Дударя по JS
Однажды и эту тему освещу однозначно, так как она глубокая и там есть о чем подробно расписать
А кто будет пользу и уникальность оценивать? Вы? Ну так всё тут всё субъективно. То что кажется Вам элементарным, для новичка будет открытием, а то что Вам кажется сложным и интересным, более шаристому челу покажется детским садом. Уровень данной статьи, я оценил как простой. Международных наград и премий за неё не требую. Это статься для фронтенд неофитов)
Уникальность, тут опять-же, много из того что тут пишется и без того есть в документации, книгах, забугорных статьях. Как будем решать что действительно уникально, а что нет? Да и блин, это просто соцсеть для гиков, а не научный журнал с полувековой историей, ТИЦем, рецензиями, блекджеком и шлюхами. Относитесь к местному контенту проще что-ли)
space2pacman
Что там копать?
Зачем? Уже все давно описали. Что вы нового добавите?
Достаточно загуглить то о чем вы пишете и как гугл так и хабр выдаст сотни материалов. Перед тем как публиковать убедитесь, что информации по вашему материалу мало.
Про какое открытие речь если гугл и хабр завален подобным материалом?
JastaFly Автор
Да много чего. Для воспитанника Гоши Дударя там разница только в том что let, новее и предпочтительнее. Ну и дай бог он ещё про разницу областей видимости знает. Для JS гуру, там куча неочевидных нюансов, let и var ведут себя в разных контекстах по разному. По разному затеняются сами и затеняют друг друга. Все эти особенности могут привести к очень неочевидным и сложно отлавливаемым сайдам
Свой взгляд на использование. Что в этом плохого?
Бесспорно выдаст, только вот моя статья будет на 2-й позиции в выдаче:
В литература есть всего 12 сюжетов. Хорошо что Вы разраб, а не драматург)
Вам знакомо понятие контекста? Я тут чётко его обозначил как раз, как открытие для новичка, а не открытие в смысле: "О боже это гениально! 2 нобелевских премии этому парню". Ну вот прикиньте для кого-то это может быть открытием с большой буквы О! Я на практике встречал код где чуваки вместо атрибутов data, запихивали служебную инфу с бека в обычные теги и скрывали их в CSS. Встречал код в котором с классами CSS, работали как с обычными строками, деструктурируя их через регулярки. Не стоит думать что, то что очевидно Вам, очевидно всем)
space2pacman
Кто такой этот ваш Гоша Дударь?
Какие контексты для операторов присвоения?
К чему?
Какой взгляд?
Есть гайка. Как ее не крути на болт результат будет одинаковый.
Взаимодействие микро сервисов может быть разное. Разработка high-load систем. Но использование атрибутов преподносится как что-то необычное со своим взглядом?
Некорректное сравнение. Вы не рассказываете про построение архитектуры приложения. Если вернутся к аналогии на литературу то ваша статья описывает правила русского языка. Как составлять повествовательные предложения. Только этот материал уже есть в сети. И у учебниках русского языка аж с советских времен.
Вопрос не про очевидность а про, что практически слово в слово такой материал уже есть во всех учебниках и онлайн библиотеках на подобии https://learn.javascript.ru/ Вы просто берете и перепечатываете.
space2pacman
Так я и предлагаю. Давайте загадим хабр вместе. Я про let и var пишу а вы про this. Договорились?
space2pacman
Если беретесь перепечатывать слово в слово то создайте примеры с кодом. Примеры веб приложений где бы это могло быть полезно, игры и т.д.
Соедините готовый материал с чем-то новым. Статья будет интереснее.
JastaFly Автор
Легенда!
Ну видимо для Вас это действительно так, просто штука объявляющая переменные. Для людей искушённых в JS у них разное поведение в блочном и глобальном контексте, разная реакция на попытки переопределения и ещё куча неожиданностей которая может возникнуть вот в такой вот базовой для любого языка фиче. Для начала задумайтесь, а с чего операторов присваивания тут вообще 2? Часто встречаете такое в других языка?!
Пока не знаю. Бумага для моей статьи по this, ещё в лесу растёт. Просто вижу что Вам эта тема, кажется чем-то чем-то элементарным, какое-то там слово this, штука в классе чтобы вызвать что-то ещё из класса. А там тоже всё не так просто)
Замете правила не меняются десятилетиями, а их носители обновляются регулярно
Это субъективщина. Вам может это и будет казаться крутым. Матёрого сеньора, мало чем удивит очередная статья, о том как реббита прикрутить к своим говносервисам
Вай нот)
Годная мысль! Возможно попробую прикрутить пример на код пене в следующий раз
space2pacman
Доброе утро
https://learn.javascript.ru/variables
Вникайте.
Вопрос не про сложно / легко. А про то, что этот материал уже давно расписан.
Бесконечно можно описывать архитектурные подходы.
А не материал про то как накручивать гайку на болт. Один раз написали накручивать по часовой, выкручивать против часовой и все.
Материал который уже есть:
Гайка на болт накручивается по часовой стрелке
Ваша статья:
Болт на гайку по стрелке часовой крутить надо и она будет накручиваться.
От этого и вопрос: Зачем?
JastaFly Автор
Да что Вы мне этим тычите. Мой вопрос был именно к Вам, а не к сухой документации и носит концептуально прикладной характер. Зачем разрабам языка понадобилось 2 ключевых слова, для объявления переменных?! Много Вы знаете языков где ещё так?!
Опять же субъективщина. По архитектуре всё тоже писано, переписано уже по 10 раз. Просто конкретно Вам, на конкретно Вашем уровне это кажется крутым. А кому-то нет. А кому-то интересно будет и статью по HTML прочесть. Устал уже в который раз писать, столь примитивную мысль
space2pacman
Потому что там все расписано: что, зачем и почему. К чему тут философствовать?
Ответ уже есть почему два оператора. А точнее три. А вы хотите рассуждения в обход книг и документации чтобы что?
space2pacman
Никому два оператора не понадобилось. Вы о чем?. Сначала появился var и спустя много лет появился let
И удалять никто не будет так как потеряется обратная совместимость.
JastaFly Автор
А к тому что именно знание подобных нюансов отличают ремесленника формошлёпа, которому что молоток, что кувалда, один фиг, от мастера с чёрным поясном по компьютер сайнс
Тогда логичный вопрос, а зачем тогда они понадобились разрабам JS? Они что особенные? Ну вот не было бы let и что тогда? Вы бы разницу заметили?
О том что вы даже не понимая разницы между var и let, критикуете статью затрагивающую более комплексный механизм языка :D
space2pacman
Знания. А не философствование. Вместо прочтения статьи и моих ответов. Вы почему-то до сих пор мне задаете вопрос про два оператора. Я вам дал избыточный ответ. Почему вы продолжаете спрашивать вместо поглощение знаний?
Вы читаете, что я пишу и скидываю?