Если вы передаете данные в элемент DOM с сервера, вы должны установить данные для элемента:
<a id="foo" data-foo="bar" href="#">foo!</a>
Доступ к данным можно получить с помощью .data()
в jQuery:
console.log( $('#foo').data('foo') );
//outputs "bar"
Однако, когда вы сохраняете данные на узле DOM в jQuery , используя данные , переменные сохраняются на узле object . Это делается для размещения сложных объектов и ссылок, так как данные хранятся на узле element , поскольку атрибут будет содержать только строковые значения.
Продолжая мой пример сверху:
$('#foo').data('foo', 'baz');
console.log( $('#foo').attr('data-foo') );
//outputs "bar" as the attribute was never changed
console.log( $('#foo').data('foo') );
//outputs "baz" as the value has been updated on the object
Кроме того, соглашение об именах для атрибутов данных имеет некоторую скрытую "ошибку":
HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('fooBarBaz') );
//outputs "fizz-buzz" as hyphens are automatically camelCase'd
Ключ дефиса по-прежнему будет работать:
HTML:
<a id="bar" data-foo-bar-baz="fizz-buzz" href="#">fizz buzz!</a>
JS:
console.log( $('#bar').data('foo-bar-baz') );
//still outputs "fizz-buzz"
Однако для объекта, возвращаемого .data()
, не будет установлен дефис-ключ:
$('#bar').data().fooBarBaz; //works
$('#bar').data()['fooBarBaz']; //works
$('#bar').data()['foo-bar-baz']; //does not work
Именно по этой причине я предлагаю избегать дефис-ключа в javascript.
Для HTML продолжайте использовать дефисную форму. Атрибуты HTML должны автоматически получать в нижнем регистре ASCII , поэтому <div data-foobar></div>
, <DIV DATA-FOOBAR></DIV>
и <dIv DaTa-FoObAr></DiV>
должны считаться идентичными, но для лучшей совместимости строчная форма должна быть предпочтительной.
Метод .data()
также выполнит некоторое базовое автоматическое приведение, если значение соответствует распознанному шаблону:
HTML:
<a id="foo"
href="#"
data-str="bar"
data-bool="true"
data-num="15"
data-json='{"fizz":["buzz"]}'>foo!</a>
JS:
$('#foo').data('str'); //`"bar"`
$('#foo').data('bool'); //`true`
$('#foo').data('num'); //`15`
$('#foo').data('json'); //`{fizz:['buzz']}`
Эта способность автоматического приведения очень удобна для создания экземпляров виджетов и плагинов:
$('.widget').each(function () {
$(this).widget($(this).data());
//-or-
$(this).widget($(this).data('widget'));
});
Если вам абсолютно необходимо иметь исходное значение в виде строки, вам нужно использовать .attr()
:
HTML:
<a id="foo" href="#" data-color="ABC123"></a>
<a id="bar" href="#" data-color="654321"></a>
JS:
$('#foo').data('color').length; //6
$('#bar').data('color').length; //undefined, length isn't a property of numbers
$('#foo').attr('data-color').length; //6
$('#bar').attr('data-color').length; //6
Это был надуманный пример. Для хранения значений цвета я использовал числовую шестнадцатеричную запись (то есть 0xABC123), но стоит отметить, что hex был неправильно проанализирован в версиях jQuery до 1.7.2 и больше не анализируется в Number
по состоянию на jQuery 1,8 RC 1.
jQuery 1.8 RC 1 изменил поведение авто-кастинга . Ранее любой формат, который являлся допустимым представлением Number
, приводился к Number
. Теперь числовые значения автоматически приводятся, только если их представление остается прежним. Это лучше всего иллюстрируется на примере.
HTML:
<a id="foo"
href="#"
data-int="1000"
data-decimal="1000.00"
data-scientific="1e3"
data-hex="0x03e8">foo!</a>
JS:
// pre 1.8 post 1.8
$('#foo').data('int'); // 1000 1000
$('#foo').data('decimal'); // 1000 "1000.00"
$('#foo').data('scientific'); // 1000 "1e3"
$('#foo').data('hex'); // 1000 "0x03e8"
Если вы планируете использовать альтернативные числовые синтаксисы для доступа к числовым значениям, обязательно сначала приведите значение к Number
, например, с унарным оператором +
.
JS (продолжение):
+$('#foo').data('hex'); // 1000