data-атрибуты и внутреннее хранилище jQuery

Содержание:
  1. Назначение HTML 5 data-атрибутов
  2. Работа с data-атрибутами посредством методов attr и removeAttr
  3. jQuery - data-атрибуты и метод data
  4. Методы для работы с data-хранилищем jQuery
  5. Комментарии

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

jQuery - Data

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

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

<div data-role="Молочные продукты" data-name="Молоко" data-present="true" data-options='{"volume":"1 литр","price":"80 руб."}'></div>
<!--
Элемент, имеющий следующие атрибуты data:
  data-role - Молочные продукты;
  data-name - Молоко;
  data-present - true;
  data-options - {"volume":"1 литр","price":"80 руб."}
-->

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

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

// получить значение атрибута data у первого элемента текущего набора
$('селектор').attr('data-*');

// добавить или изменить значение атрибута data у всех выбранных элементов
$('селектор').attr('data-*','значение');

// удалить значение атрибута data у всех найденных элементов
1 способ - с помощью attr
$('селектор').attr('data-*',null);
2 способ - с помощью removeAttr
$('селектор').removeAttr('data-*');

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

<div id="phone-1" data-name="Смартфон LG G5" data-price="39990 руб."></div>
<script>
// получим значения data-атрибутов
var phoneInfo =  'Наименование: ' + $('#phone-1').attr('data-name') + '; Цена: ' + $('#phone-1').attr('data-price');
// вывести значения в консоль
console.log(phoneInfo);
</script>

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

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

$('#phone-1').attr('data-year', 2016);

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

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

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

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

Метод data и внутреннее хранилище jQuery

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

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

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

<div id="book-1" data-name="HTML для чайников" data-price="420 руб."></div>

<script>
// это действие поместит data-атрибут price в хранилище (если его нет в хранилище)
$('#book-1').data('price'); //значение 420 руб.
// изменим значение data-атрибута price элемента с помощью attr
$('#book-1').attr('data-price','513 руб.');
// прочитаем значение price (т.к. данное значение есть в хранилище $.cache, то оно будет взято из него)
$('#book-1').data('price'); //значение 420 руб.
// удалим ключ price, который связан с элементом book-1, из хранилища
$('#book-1').removeData('price');
// прочитаем значение price (т.к. данного значения нет в хранилище jQuery, то оно будет взято из data-атрибута и помещено в $.cache)
$('#book-1').data('price'); //значение 513 руб.
</script>
Как метод jQuery data работает с атрибутами data

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

<div id="pencil" data-color="Зелёный"></div>

<script>
// если у элемента div с id="pencil" нет ключа color в хранилище jQuery, то прочитаем значение атрибута data-pencil и поместим его значение в $.cache
$('#pencil').data('color');
</script>

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

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

Парсинг методом data значений data-атрибутов

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

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

$('селектор').data('ключ');

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

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

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

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

// вызов метода data осуществляется без аргументов
$('селектор').data();

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

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

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

// 1 вариант (сохранить указанную пару ключ-значение для каждого выбранного элемента):
$('селектор').data(ключ,значение);
// ключ (строка)
// значение (данные любого типа)

// 2 вариант (установить набор пар ключ-значение (объект) для всех найденных элементов):
$('селектор').data(obj);
// obj - объект JavaScript, содержащий пары ключ-значение

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

<div id="book-js" data-name="JavaScript" data-price="890"></div>

<script>
//помещение в хранилище jQuery ключа price со значением 550
$('#book-js').data('price',550);
// прочитать информацию, связанную с элементом #book-js из хранилища (автоматическое помещение data-атрибута name в хранилище)
$('#book-js').data();
// получим значение ключа price элемента #book-js
$('#book-js').data('price'); // 550
// получим значение ключа price элемента #book-js
$('#book-js').data('name'); // "JavaScript"
</script>

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

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

Метод removeData

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

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

// 1 вариант - без параметров (удаляет все данные, связанные с текущим элементом, из внутреннего контейнера jQuery. Если в результате выборки будет возвращено несколько элементов, то метод removeData выполнит своё действие (удаление данных из $.cache) для каждого элемента.
$('селектор').removeData();

// 2 вариант - со строковым параметром, содержащим название ключа, который необходимо удалить у всех найденных элементов
$('селектор').removeData('ключ');

// 3 вариант - предназначен для удаления несколько пар данных,  связанных с элементом, из внутреннего хранилища jQuery
$('селектор').removeData('ключ1 ключ2 ...');

// 4 вариант - аналогичен 3 варианту, только ключи указываются посредством массива
$('селектор').removeData(['ключ1','ключ2',...]);

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

<div id="book-js" data-name="JavaScript для профессионалов" data-price="970"></div>

<script>
// чтение всех ключ у элемента #book-js (автоматическое помещение data-атрибутов в data-контейнер jQuery)
$('#book-js').data();
// удаление 2 ключей, связанных с #books-js из data-контейнера jQuery
$('#book-js').removeData(['price','name']);
</script>

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

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

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

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

// 1 вариант - сохранение информации в jQuery хранилище
$.data(element,key,value);
// element - DOM-элемент, с которым будет связана пара ключ-значение
// key - ключ (строка), который будет ассоциироваться со значением
// value - значение (любой тип данных за исключением undefined)

// 2 вариант - получение информации из jQuery хранилища
$.data(element,key);
// element - DOM-элемент, ассоциированный с данными
// key - название, с которым связано искомое значение

// 3 вариант - возвращение всех данных связанных с указанным элементом из data-хранилища
$.data(element);
// element - DOM-элемент, связанный с данными

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

<div id="book-html"></div>

<script>
// сохранение в хранилище информации, связанной с элементом id="book-html"
$.data(document.getElementById('book-html'),'name','HTML в действии');
// добавление ещё одной порции информации, связанной с этим же элементом
$.data(document.getElementById('book-html'),'price','760');
"760"
// получение данных из хранилища jQuery, связанных с элементом id="book-html", в виде объекта
var obj = $.data(document.getElementById('book-html'));
// получения значения name объекта
var name = obj.name;
// получения значения price объекта
var price = obj.price;
<script>

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

Эта функция также как и метод removeData применяется для удаления данных из внутреннего хранилища jQuery.

$.removeData() является низкоуровневой функцией, также как и $.data(). Поэтому более удобным вариантом является использование метода data() вместо функции $.data().

Использование функции jQuery.removeData():

// 1 вариант - удаление всей информации из хранилища связанной с указанным элементом
$.removeData(element);
// element - DOM-элемент, с которым связаны данные, подлежащие удалению

// 2 вариант - удаляет пару ключ-значение из набора данных связанных с указанным элементом
$.removeData(element,key);
// element - DOM-элемент, ассоциированный с данными
// key - ключ, определяющий набор информации (ключ-значение), который необходимо убрать из data-контейнера jQuery

Демонстрация использования функции removeData:

<div id="book-css" data-name="CSS для профессионалов" data-price="1170"></div>

<script>
// помещение атрибутов data в хранилище jQuery
$('#book-css').data();
// получения ключа price из хранилища jQuery
$('#book-css').data('price'); // 1170
// получения ключа name из хранилища jQuery
$('#book-css').data('name'); // "CSS для профессионалов"
// удаление из хранилища ключа price
$.removeData(document.getElementById('book-css'),'price');
// при получении несуществующего ключа элемента получаем значение undefined
$.data(document.getElementById('book-css'),'price'); //undefined
</script>

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

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

Применение $.hasData():

$.hasData(element);
// element - DOM-элемент, который нужно проверить на наличие данных в $.cache

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


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

jQuery - Использование data-хранилища для собственных целей

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

<div id="book-css"></div>

<script>
// проверка данных во внутреннем хранилище связанных с элементом #book-css
$.hasData(document.getElementById('book-css')); //false
// поместим значение во внутреннее хранилище
$('#book-css').data('name','CSS для профессионалов');
// проверка данных во внутреннем хранилище связанных с элементом #book-css
$.hasData(document.getElementById('book-css')); //true
// удалим значение из внутреннего хранилища
$.removeData(document.getElementById('book-css'));
// проверка данных во внутреннем хранилище связанных с элементом #book-css
$.hasData(document.getElementById('book-css')); //false
</script>

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

Комментарии: 12

Alexsey
Alexsey
Разбираюсь с примерами, возник вопрос по команде $.cache в консоли Chrome.
При выполнении возвращает undefined. Хотя судя по скриншотам выше должен возвращать Объект.
Александр Мальцев
Александр Мальцев
$.cache доступен только в jQuery 1.12.4. Начиная с jQuery 2 доступа к внутреннему хранилищу нет.
Amsterdam
Amsterdam
Александр, добрый день!
Не совсем по теме может быть, но как записать в куки удаление динамического блока? То есть, посредством аякса на странице появляется хинт с сообщением, и «крестиком» для закрытия. Если пользователь его закрыл, нужно сделать так, чтобы при переходе по страницам сайта он больше не появлялся в рамках данной сессии пока пользователь не закрыл сайт). Если человек вернулся, то блок показывать снова.
Сейчас все просто:
<div class="hint">Текст сообщения<span class="cross">X</span></div>

$(document).on('click', '.cross', function() {
  $('.hint').remove();
});
А вот как записать удаление в куки, не могу понять…
Александр Мальцев
Александр Мальцев
Привет!
Работа с cookies удобно выполнять через библиотеку, например, js-cookie.
Например:
$('.hint').remove();
Cookies.set('hint', '1');
Далее в нужном месте кода следует получить значение ключа hint из куки. Если он не равен 1, то показываете сообщение.
Amsterdam
Amsterdam
Спасибо! Пробую, но не получается получить кукис

Cookies.get('hint'); 
alert(hint);
и так

var cookhint = Cookies.get('hint'); 
alert(cookhint);
получаю undefined
Александр Мальцев
Александр Мальцев
Библиотеку js-cookie подключили?
Пример работы c js-cookie
Amsterdam
Amsterdam
Да, все подключено все работает. Немного ошибся в синтаксисе, а так получилось, спасибо огромное, Александр!!!
Amsterdam
Amsterdam
Такой код пока получился:

$( document ).on( "click", ".cross", function() {
  $('.hint').remove();
  Cookies.set('hint', '1');
});

$( document ).ready(function() {
    var cookhint = Cookies.get('hint'); 
if (cookhint >= 1) {
  $('.hint').remove();
}
else {}
});
Только загрузку аяксового хинта не отлавливает. Если просто загружать то работает, а через аякс, нет. Пытаюсь доработать
Александр Мальцев
Александр Мальцев
В AJAX запросе после того, как получили успешный ответ от сервера или до его выполнения в зависимости от того, как вам нужно, необходимо просто тоже добавьте подобный код.
Amsterdam
Amsterdam
Там через аяксовый плагин движка загружается сообщение. Через .on click отлавливается, а как прочитать, что элемент загрузился через аякс, не понял пока
Александр Мальцев
Александр Мальцев
Тогда нужно в AJAX запросе после того, как получили успешный ответ от сервера создать событие:
$(document).trigger('cookhint');
А затем создать обработчик (он сработает, как только это событие произойдёт):
$(document).on('cookhint', function () {
  ...
});
Amsterdam
Amsterdam
Понял! Отлично, получилось. Спасибо еще раз, Александр!!!