Домой / Социальные сети / Где формируется объект data js. Предопределенные объекты языка JavaScript. Форматирование и вывод дат

Где формируется объект data js. Предопределенные объекты языка JavaScript. Форматирование и вывод дат

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

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

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

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

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

Data-атрибуты HTML5

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

Пользовательские data-атрибуты:

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

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

Var msglist = document.getElementById("msglist"); var show = msglist.getAttribute("data-list-size"); msglist.setAttribute("data-list-size", +show+3);

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

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

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

Var msglist = $("#msglist"); var show = msglist.data("list-size"); msglist.data("list-size", show+3);

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

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

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

Имя атрибута Имя в API набора данных
data-user user
data-maxage maxage
data-list-size listSize

Наш новый код:

Var msglist = document.getElementById("msglist"); var show = msglist.dataset.listSize; msglist.dataset.listSize = +show+3;

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

22 ответа

Отборочные

JavaScript имеет только один тип данных, который может содержать несколько значений: Объект . Массив - это особая форма объекта.

(Plain) Объекты имеют вид

{key: value, key: value, ...}

Массивы имеют форму

Оба массива и объекты отображают структуру key -> value . Ключи в массиве должны быть числовыми, тогда как любая строка может использоваться как ключ в объектах. Пара ключей-значений также называется "свойствами" .

Доступ к свойствам можно получить либо с помощью точечной нотации

Const value = obj.someProperty;

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

// the space is not a valid character in identifier names const value = obj["some Property"]; // property name as variable const name = "some Property"; const value = obj;

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

Const value = arr; // arr.5 would be a syntax error // property name / index as variable const x = 5; const value = arr[x];

Подождите... как насчет JSON?

JSON - это текстовое представление данных, подобно XML, YAML, CSV и другим. Чтобы работать с такими данными, сначала необходимо преобразовать их в типы данных JavaScript, то есть массивы и объекты (и как это было объяснено). Как разбирать JSON объясняется в вопросе Parse JSON в JavaScript? .

Дополнительный материал для чтения

Как получить доступ к массивам и объектам является фундаментальным знанием JavaScript, и поэтому рекомендуется прочитать Руководство по JavaScript MDN , особенно разделы

Доступ к вложенным структурам данных

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

Вот пример:

Const data = { code: 42, items: [{ id: 1, name: "foo" }, { id: 2, name: "bar" }] };

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

Вот как мы можем сделать это шаг за шагом:

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

Data.items

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

Data.items

Это значение является объектом, и мы снова используем точечную нотацию для доступа к свойству name . Поэтому мы в итоге получаем:

Const item_name = data.items.name;

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

Const item_name = data["items"]["name"];

Я пытаюсь получить доступ к свойству, но получаю только undefined назад?

В большинстве случаев, когда вы получаете undefined , объект/массив просто не имеет свойства с этим именем.

Const foo = {bar: {baz: 42}}; console.log(foo.baz); // undefined

В качестве альтернативы for...in с hasOwnProperty вы можете использовать Object.keys для получить массив имен свойств:

Object.keys(data).forEach(function(prop) { // `prop` is the property name // `data` is the property value });

Массивы

Чтобы перебрать все элементы массива data.items , мы используем цикл for:

For(let i = 0, l = data.items.length; i < l; i++) { // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration // we can access the next element in the array with `data.items[i]`, example: // // var obj = data.items[i]; // // Since each element is an object (in our example), // we can now access the objects properties with `obj.id` and `obj.name`. // We could also use `data.items[i].id`. }

Можно также использовать for...in для итерации по массивам, но есть причины, по которым этого следует избегать: Почему "для (элемент var в списке)" с массивами, считающимися плохими практика в JavaScript? .

При увеличении поддержки браузера ECMAScript 5 метод массива forEach становится интересным альтернатива:

Data.items.forEach(function(value, index, array) { // The callback is executed for each element in the array. // `value` is the element itself (equivalent to `array`) // `index` will be the index of the element in the array // `array` is a reference to the array itself (i.e. `data.items` in this case) });

В средах, поддерживающих ES2015 (ES6), вы также можете использовать цикл for...of , который не только работает для массивов, но и для любого iterable :

For (const item of data.items) { // `item` is the array element, **not** the index }

В каждой итерации for...of непосредственно дает нам следующий элемент итерации, нет никакого "индекса" для доступа или использования.

Что делать, если "глубина" структуры данных мне неизвестна?

В дополнение к неизвестным ключам, "глубина" структуры данных (например, сколько вложенных объектов) она имеет, также может быть неизвестна. Как получить доступ к глубоко вложенным свойствам, как правило, зависит от точной структуры данных.

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

Вот пример, чтобы получить первый лист node двоичного дерева:

Function getLeaf(node) { if (node.leftChild) { return getLeaf(node.leftChild); // x > 0)) // false, because 3^2 is greater than 5 console.log(arr.every(x => Math.pow(x, 2) < 5)) // true, because 2 is even (the remainder from dividing by 2 is 0) console.log(arr.some(x => x % 2 === 0)) // false, because none of the elements is equal to 5 console.log(arr.some(x => x === 5))

Array.prototype.find() и Array.prototype.filter()

Методы find() возвращают первый элемент, который удовлетворяет предоставленной функции обратного вызова. Метод filter() возвращает массив всех элементов, который удовлетворяет предоставленной функции обратного вызова.

Const arr = // 2, because 2^2 !== 2 console.log(arr.find(x => x !== Math.pow(x, 2))) // 1, because it the first element console.log(arr.find(x => true)) // undefined, because none of the elements equals 7 console.log(arr.find(x => x === 7)) // , because these elements are greater than 1 console.log(arr.filter(x => x > 1)) // , because the function returns true for all elements console.log(arr.filter(x => true)) // , because none of the elements equals neither 6 nor 7 console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

Метод map() возвращает массив с результатами вызова предоставленной функции обратного вызова для элементов массива.

Const arr = console.log(arr.map(x => x + 1)) // console.log(arr.map(x => String.fromCharCode(96 + x))) // ["a", "b", "c"] console.log(arr.map(x => x)) // (no-op) console.log(arr.map(x => Math.pow(x, 2))) // console.log(arr.map(String)) // ["1", "2", "3"]

Array.prototype.reduce()

Метод reduce() уменьшает массив до одного значения, вызывая предоставленную функцию обратного вызова с двумя элементами.

Const arr = // Sum of array elements. console.log(arr.reduce((a, b) => a + b)) // 6 // The largest number in the array. console.log(arr.reduce((a, b) => a > b ? a: b)) // 3

Метод reduce() принимает необязательный второй параметр, который является начальным значением. Это полезно, когда массив, на который вы вызываете reduce() , может иметь нуль или один элемент. Например, если бы мы хотели создать функцию sum() , которая принимает массив в качестве аргумента и возвращает сумму всех элементов, мы могли бы написать это следующим образом:

Const sum = arr => arr.reduce((a, b) => a + b, 0) console.log(sum()) // 0 console.log(sum()) // 4 console.log(sum()) // 7

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

const data = { code: 42, items: [{ id: 1, name: "foo" }, { id: 2, name: "bar" }] }; const { items: [, { name: secondName }] } = data; console.log(secondName);

В приведенном выше примере создается переменная с именем secondName из ключа name из массива, называемого items , одинокая, говорит, пропускает первый объект в массиве.

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

Это очень краткое введение в ваш конкретный прецедент, деструктурирование может быть необычным синтаксисом, чтобы привыкнуть к нему. Я бы порекомендовал вам прочитать документацию по назначению Mozilla Destructuring Assignment, чтобы узнать больше.

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

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

Data["items"]["name"]

это тоже работает -

Data.items.name data["items"].name data.items["name"]

Когда вы не знаете точного имени заранее, или пользователь предоставляет вам имя. Затем требуется динамический поиск по структуре данных. Некоторые предположили, что поиск может быть выполнен с использованием цикла for , но существует очень простой способ обхода пути с использованием Array.reduce .

Const data = { code: 42, items: [{ id: 1, name: "foo" }, { id: 2, name: "bar" }] } const path = [ "items", "1", "name"] let result = path.reduce((a,v) => a[v], data)

Путь - это способ сказать: сначала возьмите объект с ключевыми items , который оказывается массивом. Затем возьмите 1 элемент -st (0 индексных массивов). Последнее, возьмите объект с name ключа в этом элементе массива, который является строкой bar .

Если у вас очень длинный путь, вы можете даже использовать String.split чтобы сделать все это проще -

"items.1.name".split(".").reduce((a,v) => a[v], data)

Это просто обычный JavaScript, без использования сторонних библиотек, таких как jQuery или lodash.

Использование JSONPath будет одним из самых гибких решений, если вы хотите включить библиотеку: https://github.com/s3u/JSONPath (node и браузер)

Для вашего случая использования путь json:

$..items.name

Var secondName = jsonPath.eval(data, "$..items.name");

Var ourStorage = { "desk": { "drawer": "stapler" }, "cabinet": { "top drawer": { "folder1": "a file", "folder2": "secrets" }, "bottom drawer": "soda" } }; ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

//parent.subParent.subsubParent["almost there"]["final property"]

В основном, используйте точку между каждым потомком, который разворачивается под ним, и когда у вас есть имена объектов, состоящие из двух строк, вы должны использовать нотацию ["obj Name"]. В противном случае достаточно точки;

добавим, что доступ к вложенным массивам будет происходить так:

Var ourPets = [ { animalType: "cat", names: [ "Meowzer", "Fluffy", "Kit-Cat" ] }, { animalType: "dog", names: [ "Spot", "Bowser", "Frankie" ] } ]; ourPets.names; // Outputs "Fluffy" ourPets.names; // Outputs "Spot"

Еще один полезный документ, описывающий описанную выше ситуацию: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation

Доступ к собственности с помощью точечного хождения: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Dot_notation

Если вы ищете один или несколько объектов, которые соответствуют определенным критериям, у вас есть несколько вариантов, используя query-js

//will return all elements with an id larger than 1 data.items.where(function(e){return e.id > 1;}); //will return the first element with an id larger than 1 data.items.first(function(e){return e.id > 1;}); //will return the first element with an id larger than 1 //or the second argument if non are found data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

Есть также single и singleOrDefault они работают так же, как first и firstOrDefault соответственно. Разница лишь в том, что они будут бросать, если найдено более одного совпадения.

для дальнейшего объяснения query-js вы можете начать с этого поста

Старый вопрос, но как никто не упоминал lodash (просто подчеркивание).

Если вы уже используете lodash в своем проекте, я думаю, что это элегантный способ сделать это в сложном примере:

Get(response, ["output", "fund", "data", "0", "children", "0", "group", "myValue"], "")

то же самое, что:

Response.output.fund.data.children.group.myValue

Разница между первой и второй опцией заключается в том, что в Оптим 1 , если у вас есть одно из отсутствующих свойств (undefined), в пути вы не получите ошибку, он возвращает вы третий параметр.

Для фильтра массива lodash есть _.find() , но я бы предпочел использовать регулярный filter() . Но я все же считаю, что вышеприведенный метод _.get() очень полезен при работе с действительно сложными данными. В прошлом я столкнулся с действительно сложными API-интерфейсами, и это было удобно!

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

Что такое библиотека JavaScript, которая предоставляет целый беспорядок полезных помощников functional programming без расширения каких-либо встроенных объектов.

Решение: var data = { code: 42, items: [{ id: 1, name: "foo" }, { id: 2, name: "bar" }] }; var item = _.findWhere(data.items, { id: 2 }); if (!_.isUndefined(item)) { console.log("NAME =>", item.name); } //using find - var item = _.find(data.items, function(item) { return item.id === 2; }); if (!_.isUndefined(item)) { console.log("NAME =>", item.name); }

Доступ к динамически многоуровневому объекту.

Var obj = { name: "salut", subobj: { subsubobj: { names: "I am sub sub obj" } } }; var level = "subobj.subsubobj.names"; level = level.split("."); var currentObjState = obj; for (var i = 0; i < level.length; i++) { currentObjState = currentObjState]; } console.log(currentObjState);

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

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

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

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

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

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

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

    Delete

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

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

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

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

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

    // Это кнопка var button = document.getElementById("your-button-id"); // Получаем значение var cmd = button.getAttribute("data-cmd"); var id = button.getAttribute("data-id"); // Изменяем значение button.setAttribute("data-cmd", yourNewCmd); button.setAttribute("data-id", yourNewId);

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

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

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

    // Получаем значение var cmd = $("#your-button-id").attr("data-cmd"); var id = $("#your-button-id").attr("data-id"); // Изменяем значение $("#your-button-id") .attr("data-cmd", yourNewCmd) .attr("data-id", yourNewId);

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

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

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

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

    // Это кнопка var button = document.getElementById("your-button-id"); // Получаем значение var cmd = button.dataset.cmd; var id = button.dataset.id; // Изменяем значение button.dataset.cmd = yourNewCmd; button.dataset.id = yourNewId;

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

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

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

    Фильтрация

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

    • Ford
    • Chevrolet
    • ...

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

    $("#filter").on("keyup", function() { var keyword = $(this).val().toLowerCase(); $(".cars > li").each(function() { $(this).toggle(keyword.length < 1 || $(this).attr("data-models").indexOf(keyword) > -1); } ); } );

    Стилизация

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

    А теперь CSS:

    { background: red; }

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

    { color: red; }

    Настройка

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

    Popover on top

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

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

    Метод data в jQuery даёт нам возможность связать произвольные данные с любым объектом документа или javaScript, что позволяет сделать ваш код более кратким и читаемым. Начиная с версии jQuery 1.4.3 появилась возможность использовать этот метод для объектов javaScript, а также отслеживать изменения этих данных.

    Основы

    Начнём с того, что вы можете вызвать метод data для jQuery объекта, а также использовать функцию $.data() напрямую.

    // Использование метода: $("#myDiv").data("key","произвольное значение"); // Использование функции напрямую: $.data($("#myDiv").get(0),"key","произвольное значение");

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

    Также, обратите внимание, что в качестве первого параметра в функцию $.data вам необходимо передавать DOM-элемент, а не объект jQuery.

    Метод объекта требует двух параметров - ключ и значение. Ключ - строковая константа, а значение - любая структура данных, включая функции массивы и объекты. Существует альтернативный синтаксис, в котором можно передавать объект как один параметр:

    // Можно передать объект: $("#myDiv").data({"name":"Stevie","age":21}); // Тоже самое: $("#myDiv").data("name","Stevie").data("age",21);

    Теперь, если вам необходимо получить сохранённые данные, вы можете вызвать функцию data , передав ей ключ в качестве параметра:

    Var theValue = $("#myDiv").data("age"); // 21

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

    Var theValue = $("div:first").data("name"); // Stevie $("div:first").click(function(){ alert($(this).data("age"); // 21 });

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

    В этом случае вы можете получить данные из атрибута data-internal-id , вызвав метод $("#img1").data("internal-id") , что несомненно удобно при AJAX-запросах.

    Использование метода data для javaScript-объектов

    Возможно, вы будете удивлены, но метод data также можно использовать для обычных объектов javaScript. Эта функциональность официально появилась в jQuery 1.4.3.

    Var myObj = {}; $(myObj).data("city","Springfield");

    Приведённый пример, в действительности создаёт свойство city для заданного объекта. Почему бы в таком случае не написать просто myObj.city = "Springfield"? А отличие в том, что метод data добавляет объекту несколько полезных событий, упрощающих работу с этим объектом. Например:

    Var progressBar = {}; $(progressBar).bind("setData",function(e,key,value){ switch(key){ case "percent": $("#progress").width(value+"%"); $("#percentText").text(value+"%"); break; case "color": $("#progress").css("color",value); break; case "enabled": $("#progress").toggleClass("active",value); break; } }); $(progressBar).data("enabled",true).data("percent",21).data("color","green"); console.log(progressBar.enabled);

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

    Существует ещё два события, которые могут использоваться для объекта javaScript:

    • getData - срабатывает перед чтением данных. Вы можете использовать его для предобработки получаемых данных. Например, для пересчёта значения.
    • changeData - срабатывает когда данные устанавливаются или изменяются. Это событие используется в плагине jQuery datalink . С его помощью можно связать данные формы с объектом javaScript и работать с полями формы как со свойствами объекта.
    За кулисами

    jQuery создаёт пустой объект (для любопытных, он называется $.cache), который и является хранилищем всех значений, которые вы сохраняете с помощью метода data . Каждому элементу из DOM, который используется с методом data , присваивается уникальный идентификатор, который затем является ключом для доступа к данным в объекте $.cache .

    jQuery хранит в этом кэше не только пользовательские данные, туда попадают также внутренние данные, обработчики событий, которые вы навешиваете с помощью функций live() , bind() и delegate() . Использование центрального хранилища делает jQuery более надёжным.

    Заключение

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

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

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

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

    Работа с 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" в консоль браузера:

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

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

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

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

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

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

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

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



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

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

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

    // это действие поместит 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 руб.

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

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

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

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

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

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

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

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

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

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

    //помещение в хранилище 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"

    Методы для работы с 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:

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

    Функция $.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:

    // сохранение в хранилище информации, связанной с элементом 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;

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

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

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

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

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

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

    // помещение атрибутов 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

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

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

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

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

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

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



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

    // проверка данных во внутреннем хранилище связанных с элементом #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

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