Sdscompany.ru

Компьютерный журнал
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Data model html

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

Когда браузер загружает страницу, он «читает» (также говорят: «парсит») HTML и генерирует из него DOM-объекты. Для узлов-элементов большинство стандартных HTML-атрибутов автоматически становятся свойствами DOM-объектов.

Например, для такого тега у DOM-объекта будет такое свойство body.id=»page» .

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

DOM-свойства

Ранее мы уже видели встроенные DOM-свойства. Их много. Но технически нас никто не ограничивает, и если этого мало – мы можем добавить своё собственное свойство.

DOM-узлы – это обычные объекты JavaScript. Мы можем их изменять.

Например, создадим новое свойство для document.body :

Мы можем добавить и метод:

Также можно изменять встроенные прототипы, такие как Element.prototype и добавлять новые методы ко всем элементам:

Итак, DOM-свойства и методы ведут себя так же, как и обычные объекты JavaScript:

  • Им можно присвоить любое значение.
  • Они регистрозависимы (нужно писать elem.nodeType , не elem.NoDeTyPe ).

HTML-атрибуты

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

Таким образом, когда у элемента есть id или другой стандартный атрибут, создаётся соответствующее свойство. Но этого не происходит, если атрибут нестандартный.

Пожалуйста, учтите, что стандартный атрибут для одного тега может быть нестандартным для другого. Например, атрибут «type» является стандартным для элемента (HTMLInputElement), но не является стандартным для (HTMLBodyElement). Стандартные атрибуты описаны в спецификации для соответствующего класса элемента.

Мы можем увидеть это на примере ниже:

Таким образом, для нестандартных атрибутов не будет соответствующих DOM-свойств. Есть ли способ получить такие атрибуты?

Конечно. Все атрибуты доступны с помощью следующих методов:

  • elem.hasAttribute(name) – проверяет наличие атрибута.
  • elem.getAttribute(name) – получает значение атрибута.
  • elem.setAttribute(name, value) – устанавливает значение атрибута.
  • elem.removeAttribute(name) – удаляет атрибут.

Эти методы работают именно с тем, что написано в HTML.

Кроме этого, получить все атрибуты элемента можно с помощью свойства elem.attributes : коллекция объектов, которая принадлежит ко встроенному классу Attr со свойствами name и value .

Вот демонстрация чтения нестандартного свойства:

У HTML-атрибутов есть следующие особенности:

  • Их имена регистронезависимы ( id то же самое, что и ID ).
  • Их значения всегда являются строками.

Расширенная демонстрация работы с атрибутами:

Пожалуйста, обратите внимание:

  1. getAttribute(‘About’) – здесь первая буква заглавная, а в HTML – строчная. Но это не важно: имена атрибутов регистронезависимы.
  2. Мы можем присвоить что угодно атрибуту, но это станет строкой. Поэтому в этой строчке мы получаем значение «123» .
  3. Все атрибуты, в том числе те, которые мы установили, видны в outerHTML .
  4. Коллекция attributes является перебираемой. В ней есть все атрибуты элемента (стандартные и нестандартные) в виде объектов со свойствами name и value .

Синхронизация между атрибутами и свойствами

Когда стандартный атрибут изменяется, соответствующее свойство автоматически обновляется. Это работает и в обратную сторону (за некоторыми исключениями).

В примере ниже id модифицируется как атрибут, и можно увидеть, что свойство также изменено. То же самое работает и в обратную сторону:

Но есть и исключения, например, input.value синхронизируется только в одну сторону – атрибут → значение, но не в обратную:

  • Изменение атрибута value обновило свойство.
  • Но изменение свойства не повлияло на атрибут.

Иногда эта «особенность» может пригодиться, потому что действия пользователя могут приводить к изменениям value , и если после этого мы захотим восстановить «оригинальное» значение из HTML, оно будет в атрибуте.

DOM-свойства типизированы

DOM-свойства не всегда являются строками. Например, свойство input.checked (для чекбоксов) имеет логический тип:

Есть и другие примеры. Атрибут style – строка, но свойство style является объектом:

Хотя большинство свойств, всё же, строки.

При этом некоторые из них, хоть и строки, могут отличаться от атрибутов. Например, DOM-свойство href всегда содержит полный URL, даже если атрибут содержит относительный URL или просто #hash .

Если же нужно значение href или любого другого атрибута в точности, как оно записано в HTML, можно воспользоваться getAttribute .

Нестандартные атрибуты, dataset

При написании HTML мы используем много стандартных атрибутов. Но что насчёт нестандартных, пользовательских? Во-первых, давайте посмотрим, полезны они или нет? Для чего они нужны?

Иногда нестандартные атрибуты используются для передачи пользовательских данных из HTML в JavaScript, или чтобы «помечать» HTML-элементы для JavaScript.

Также они могут быть использованы, чтобы стилизовать элементы.

Например, здесь для состояния заказа используется атрибут order-state :

Почему атрибут может быть предпочтительнее таких классов, как .order-state-new , .order-state-pending , order-state-canceled ?

Это потому, что атрибутом удобнее управлять. Состояние может быть изменено достаточно просто:

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

Чтобы избежать конфликтов, существуют атрибуты вида data-*.

Все атрибуты, начинающиеся с префикса «data-», зарезервированы для использования программистами. Они доступны в свойстве dataset .

Например, если у elem есть атрибут «data-about» , то обратиться к нему можно как elem.dataset.about .

Атрибуты, состоящие из нескольких слов, к примеру data-order-state , становятся свойствами, записанными с помощью верблюжьей нотации: dataset.orderState .

Вот переписанный пример «состояния заказа»:

Использование data-* атрибутов – валидный, безопасный способ передачи пользовательских данных.

Пожалуйста, примите во внимание, что мы можем не только читать, но и изменять data-атрибуты. Тогда CSS обновит представление соответствующим образом: в примере выше последняя строка (*) меняет цвет на синий.

Как использовать data-атрибуты HTML5

Давным-давно, во времена XHTML/HTML4 у разработчиков было всего несколько возможностей, которыми они могли пользоваться для того, чтобы хранить произвольные данные, относящиеся к DOM. Вы могли изобретать свои собственные атрибуты, но это было рискованно — ваш код не был бы валидным, браузеры могли игнорировать ваши данные, и это могло вызвать проблемы, если название совпадало со стандартными атрибутами HTML.

Читать еще:  Php скрипт поиска

Поэтому большинство разработчиков завязывались на атрибуты class или rel так как они были единственным разумным способом хранить дополнительные строки. К примеру, предположим, что мы создаем виджет для отображения сообщений типа временной линии сообщений в Twitter. В идеале JavaScript должен иметь возможность конфигурирования без необходимости переписывать код, так что мы определяем идентификатор пользователя в атрибуте class, например:

Наш JavaScript код будет искать элемент с ID msglist. С помощью скрипта мы будем искать классы, начинающиеся с user_, а “bob” в нашем случае будет идентификатором пользователя, и мы отобразим все сообщения этого пользователя.

Скажем, мы бы хотели также задать максимальное количество сообщений, и пропускать сообщения старше шести месяцев (180 дней):

Наш атрибут class очень быстро загромождается — проще допустить ошибку, а разбор строк на JavaScript становится все сложнее.

Data-атрибуты HTML5

К счастью, в HTML5 была введена возможность использовать пользовательские атрибуты. Вы можете использовать любое имя в нижнем регистре с префиксом data-, например:

  • это строки — в них вы можете хранить любую информацию, которая может быть представлена или закодирована в виде строки, например JSON. Приведение типов должно осуществляться с помощью JavaScript
  • должны использоваться в тех случаях, когда нет подходящих элементов HTML5 или атрибутов
  • относятся только к странице. В отличие от микроформатов они должны игнорироваться внешними системами, типа поисковых систем и поисковых роботов

Пример №1 обработки на JavaScript: getAttribute и setAttribute

Все браузеры позволяют вам получить и изменить data-атрибуты с использованием методов getAttribute и setAttribute:

Это работает, но должно использоваться только для поддержания совместимости со старыми браузерами.

Пример №2 обработки на JavaScript: метод data() библиотеки jQuery

Начиная с версии jQuery 1.4.3 метод data() обрабатывает data-атрибуты HTML5. Вам нет необходимости явно указывать префикс data-, так что подобный код будет работать:

Но как бы то ни было, имейте в виду, что jQuery пытается конвертировать значения таких атрибутов в подхдящие типы (булевы значения, числа, объекты, массивы или null) и затронет DOM. В отличие от setAttribute, метод data() физически не заменит атрибут data-list-size — если вы проверите его значение вне jQuery — оно все еще останется равным 5.

Пример №3 обработки на JavaScript: API для работы с наборами данных

И, наконец, у нас есть API для работы с наборами данных HTML5, которое возвращает объект DOMStringMap. Необходимо помнить, что data-атрибуты отображаются в объект без префиксов data-, из названий убираются знаки дефиса, а сами названия конвертируются в camelCase, например:

Data model html

До создания HTML5 работать с атрибутами в HTML элементах, мягко говоря, не доставляло удовольствия. Приходилось использовать такие атрибуты, как rel или class . А некоторые разработчики даже создавали свои атрибуты.

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

Как же работают дата атрибуты?

Название говорит само за себя. Дата атрибуты хранят в себе какие-то данные, заданные вами. Они всегда начинаются с приставки data- и заканчиваются чем то более понятным для разработчика (по спецификации допускаются только символы нижнего регистра и дефисы). Элемент может содержать в себе любое количество дата атрибутов.

Пример использования атрибутов для хранения данных о пользоватле:

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

Приведем пример кнопки для удаления чего-либо на вашей странице:

Все необходимые параметры у вас под рукой и готовы для отправки в скрипт бекэнда. Никаких больше rel атрибутов или обработки ID или необходимого действия из других атрибутов.

Что можно хранить?

Стоить помнить только одно правило, в дата атрибутах нельзя хранить объекты. То есть, можно, если их предварительно сериализовать. Сейчас просто запомните, что, впринципе, хранить можно только строковые данные.

Чтение/запись атрибутов средствами javascript

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

Довольно просто, не так ли? Теперь просто передавайте параметры cmd и id вашему приложению и выполняйте необходимый ajax запрос.

Чтение/запись дата атрибутов при помощи jQuery.

Приведем аналог на jQuery:

Не путайте с методом data() . Хотя у них есть что-то общее, в целом это абсолютно разные вещи. Даже если вы не полностью знакомы с этими методами, просто используйте attr() .

Использование dataset API

HTML5 даже предлагает нам API для работы с data атрибутами, хотя IE10 и ниже не поддерживает его.

Опять таки пример с кнопкой, но на этот раз при помощи dataset API :

Обратите внимание на отсутсвие приставки data и дефисов. Так же как и при работе со свойтсвами CSS в JavaScript вам потребуется «горбатый» регистр. Dataset API переводит имена атрибутов таким образом что data-some-attribute-name в HTML превращается в dataset.someAttributeName в JavaScript.

Что можно делать с дата атрибутами

Приведенные примеры — это только фундамент. Вы можете выполнять гораздо более сложные операции с дата атрибутами. Давайте рассмотрим несколько примеров.

Фильтрация

Допустим вы работаете со списком элементов и вам необходимо отфильтровать их по ключевому слову. Разместите ключевые слова в data атрибутах и при помощи небольшого итерационного скрипта обработайте их.

Пример “на коленке”:

Стилизация

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

Но как же учитывать значение атрибута? Вот так можно применить стиль ко всем элементам с атрибутом data-warning чье значение содержит в себе слово error :

Настройка

Известный фреймворк Bootstrap применяет data атрибуты для настройки своих JavaScript плагинов. Пример всплывающего окна:

Лучший способ хранить данные

Дата атрибуты очень распространены в веб технологиях. Но самое важное то, что они полностью поддерживаются старыми браузерами и все глубже и глубже проникают в веб стандарты. А так стандарт HTML уже утверждён, то работать с ними можно уже сегодня и не бояться, что вдруг они пропадут завтра.

Читать еще:  Messages list html recuerda

Я привел несколько широко распространенных примеров использования дата атрибутов. Хотите продемонстрировать другие способы их применения? Использовали их раньше и хотите поделиться опытом? Оставляйте свои комментарии!

Как использовать в html 5 data-атрибуты и другие новые атрибуты

Дата публикации: 2016-03-16

От автора: приветствую вас, дорогие читатели блога webformyself. В этой статье мы продолжим говорить о технологии html5. В этот раз я хотел бы затронуть другие нововведения этой спецификации. Таковыми являются в html5 data-атрибуты, которые можно прописывать любым тегам.

Что такое data-атрибуты и для чего они нужны?

Итак, начнем с того, что же это такое вообще. Как вы возможно знаете, в html любому тегу можно указать какой-то атрибут, будь то универсальный (class, id) или уникальный для этого элемента.

Так вот, новая спецификация HTML5 добавила несколько новых атрибутов. В основном они пишутся для таких же новых тегов, но также появилась еще одна, абсолютно новая категория – data-атрибуты.

Их первая особенность в том, что атрибут может называться как угодно. Единственное правило – он должен начинаться с префикса data- и в нем, естественно, не должно быть русских букв. Одному тегу можно записать сколько угодно таких параметров. В качестве значений также можно указывать произвольные слова. Кстати, значение можно указывать и на русском. Пример:

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Как видите, можно указывать любые имена и любые значения. Но ведь эти параметры ничего не делают с элементом, зачем тогда они вообще нужны? Есть как минимум несколько способов применения data-атрибутов в сайтостроении, и давайте рассмотрим их.

Способ применения 1 – обращение к элементам в css

Если вы знаете, что такое селекторы атрибутов, то наверняка уже догадываетесь, как могут быть использованы новые возможности. Указывая для тега уникальный data-атрибут, вы сможете соответствующим образом обратиться к нему в стилях. Давайте рассмотрим пример:

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

Способ применения 2 – хранение значений и их использование

С первого взгляда, значения data-атрибутов ничего не меняют и вообще никак не влияют на веб-страницу. Так зачем они вообще нужны? На самом деле применение им найти можно, если вспомнить про функцию attr() в css.

Практический курс по верстке адаптивного сайта с нуля!

Изучите курс и узнайте, как верстать современные сайты на HTML5 и CSS3

Давайте поставим задачу: нужно вывести на страницу поясняющий текст к фотографиям, который появлялся бы либо сразу с загрузкой картинки, либо при наведении на нее, не важно как. Стандартная подсказка реализуется с помощью атрибута title.

Но такая подсказка может не удовлетворять вас по очень многим параметрам. Во-первых, она появляется плавно (что не всегда нужно). Во-вторых, она исчезает через какое-то время. В-третьих, она появляется в разных местах, в зависимости от того, куда наведен курсор. Ну а самая большая проблема – мы никак не можем стилизовать нашу подсказку – это всегда будет черный текст на белом фоне, что не очень интересно.

Итак, выше в коде мы вставили картинку, указали путь к ней и дополнительно записали произвольный data-параметр. Реализовать вывод пояснения к фото теперь можно таким образом:

Что мы сделали? Теперь у всех изображений будет псевдоэлемент, в котором будет находиться значение атрибута data-img, если оно есть у тега img. Таким нехитрым способом вы смогли вывести поясняющий текст к фотографии.

Я не буду в этой статье приводить инструкцию, как оформить подсказку. Скажу только, что по умолчанию она будет отображаться после загрузки страницы. Зачастую ее нужно изначально скрыть, а выводить при наведении на картинку. Чтобы это реализовать, вам нужно воспользоваться селектором img:hover:after.

Ну а какие есть еще html5 атрибуты, появившиеся только в этой спецификации? К таковым можно отнести, например, controls – атрибут для новых элементов audio и video, который позволяет вывести элементы управления видеороликом или аудиозаписью.

У видео с помощью параметра poster можно указать путь к изображению, которое будет фоном до начала просмотра видео. В общем, вот таких вот мелких атрибутов появилось не так уж и мало.

Также у одиночного элемента input появилось очень много новых параметров. Теперь можно создавать поля для ввода электронной почты, телефона, выбора календарной даты или времени, поле для выбора цвета и т.д. Пустой атрибут required делает любое поле обязательным для заполнения, если этого не сделать, то браузер просто не пропустит отправку формы.

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

Упрощенный синтаксис

Не могу не упомянуть о том, как правильно записывать атрибуты и их значения. Дело в том, что HTML 5 в этом плане стал гораздо более простым. Достаточно указать , и можно писать код даже с небольшими ошибками, а в результате он все равно будет обработан правильно. Примеры:

jQuery — Data

Статья, в которой рассмотрим, какие в jQuery существуют методы для работы с data-атрибутами и внутренним хранилищем Data.

Назначение HTML 5 data-атрибутов

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

Читать еще:  Html dropdownlist mvc

Работа с data-атрибутами посредством методов attr и removeAttr

Выполнение действий над атрибутами data в jQuery обычно осуществляется с помощью методов: attr и removeAttr .

Например, выведем значение data-атрибутов элемента div с id=»phone-1″ в консоль браузера:

Данный метод (attr) возвращает значение data-атрибута в виде строки.

Например, добавим атрибут data-year к вышеприведённому элементу:

Более детально разобраться, как работать с данными методами можно в статье jQuery — Работа с атрибутами HTML элементов.

jQuery — data-атрибуты и метод data

Метод data используется в jQuery не для общения с data-атрибутами. Его основное предназначение — это чтение данных из внутреннего хранилища jQuery ( $.cache ) или запись в него некоторой информации.

Внутреннее хранилище jQuery — это некий контейнер, в который можно помещать произвольную информацию, связанную с определённым DOM-элементом текущей страницы.

Но, тем не менее, данный метод может выполнять чтение HTML5 data-атрибутов, и помещать их во внутреннее хранилище. Это случается только в том случае, если в хранилище jQuery нет ключа с именем, равным имени data-атрибута. В противном случае вы получите значение из хранилища $.cache .

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

Пример, в котором рассмотрим, как метод data работает с data-атрибутом:

В методе data ключ соответствует имени data-атрибута без приставки data- .

Кроме этого, если в окончании имени data-атрибута (после data- ) содержится дефисы («-«), то при обращении к нему с помощью метода data буквы стоящие перед дефисом должны быть заменены на заглавные, а сами дефисы убраны. Например, имя атрибута data-last-name должно быть указано в методе data как lastName .

Ещё один момент при работе с методом data заключается в том, что когда jQuery разбирает значение data-атрибута, то он пытается привести его значение (строку) к соответствующему типу JavaScript (булевскому значению, числу, объекту, массиву или null ). Например, значение «420» преобразуется в число 420. Если значение data-атрибута является объектом (начинается с » < ") или массивом (начинается с " [ "), то jQuery использует для разбора значения метод parseJSON . Это означает то, что содержимое атрибута должно иметь валидный JSON синтаксис (включая указания имен свойств в двойных кавычках). Но если попытка разобрать значение data-атрибута окажется не удачной, то оно останется в исходном в виде (т.е. в виде строки).

В итоге, метод data используется для выполнения следующих операций (в зависимости от указанных аргументов):

1. Получение значения ключа, связанного с элементом, из внутреннего хранилища jQuery:

Данный вариант метода data выполняет одно из следующих действий:

  • Чтение data-атрибута (имя которого соответствует указанному ключу) у первого элемента текущего набора, помещение его в хранилище, и возвращение значение этого ключа в качестве результата. Данное действие данный метод выполняет только в том случае, если у элемента есть data-элемент соответствующий ключу и в контейнере $.cache у данного элемента нет записи с указанным ключом.
  • Получает значение указанного ключа из хранилища jQuery. Это действие метод data выполняет только в том случае, если в $.cache у элемента есть указанный ключ.
  • возвращает значение undefined или пустой объект, если ни одно из вышеперечисленных действий не выполняется.

Если в результате выборки $(‘селектор’) возвращается несколько элементов, то данный метод возвращает значение только для первого элемента из полученного набора.

2. Получение всех данных в виде объекта JavaScript из хранилища jQuery, связанных с указанным элементом:

Более детально этот вариант метода data осуществляет следующее:

  1. Автоматически помещает data-атрибуты во внутреннее хранилище jQuery. Это действие он выполняет только для тех data-атрибутов, имён (ключей) которых нет на текущий момент в хранилище jQuery.
  2. Возвращает объект, состоящий из пар ключ-значение, связанных с текущим элементом.

3. Метод data применяют не только для чтения значений, но и для записи данных (ключ-значение), ассоциированных с некоторым элементом DOM во внутреннее хранилище jQuery.

Пример работы с методом data :

Методы для работы с data-хранилищем jQuery

Рассмотрим, какие ещё есть методы в jQuery для работы с data хранилищем кроме data .

Метод removeData

Данный метод предназначен для удаления данных, связанных с определённым элементом, из внутреннего хранилища jQuery. Данный метод не работает с data-атрибутами, поэтому все соответствующие ключу data-атрибуты удалены не будут.

Синтаксис метода removeData :

Удалим несколько пар ключ-значений, ассоциированных с элементом с id=»book-js» из хранилища jQuery:

Функция $.data()

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

Данная функция предназначена только для работы с jQuery хранилищем и в отличие от метода $(‘селектор’).data() не извлекает данные из HTML 5 data-атрибутов.

Синтаксис функции jQuery.data() :

Пример использования функции $.data() для сохранения информации, связанной с определённым DOM-элементом, в хранилище jQuery:

Функция $.hasData()

Эта функция определяет, имеет ли элемент, какие-либо данные во внутреннем хранилище jQuery.

Функция hasData возвращает true , если в хранилище есть какие-либо данные связанные с указанным элементом. В противном случае данная функция возвращает false .

Внутреннее хранилище $.cache используется также самой библиотекой jQuery. Один из примеров — это использование его для хранения кода обработчиков событий jQuery.

Пример использования функции hasData :

Разобраться, как работать в jQuery с data-атрибутами, которые появились в спецификации языка HTML5, можно в статье «jQuery – Методы attr и removeAttr». Эти методы ( attr и removeAttr ) используются не только для управления data-атрибутами, но и любых других атрибутов HTML элементов.

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт
Adblock
detector