jQuery Data vs Attr?


513

Яка різниця у використанні між $.dataта $.attrпри використанні data-someAttribute?

Я розумію, що $.dataвін зберігається в jQuery $.cache, а не в DOM. Тому, якщо я хочу використовувати $.cacheдля зберігання даних, я повинен використовувати $.data. Якщо я хочу додати атрибути даних HTML5, я повинен використовувати $.attr("data-attribute", "myCoolValue").


5
будь ласка, прочитайте це: forum.jquery.com/topic/when-to-use-attr-vs-data
Baz1nga

14
@zzz За винятком того, що він насправді не відповідає на питання ...?
sdleihssirhc

2
Насправді це робить, опосередковано. Приєднання об'єкта через attr()може призвести до витоку пам'яті (принаймні, в IE), а використання data()безпечно. Він натякає на це у своїй відповіді, хоча прямо не виходить і не каже цього. Більше інформації про документи jQuery (див. "Додаткові примітки"): api.jquery.com/attr
ken

6
@John B, просто FYI (навіть якщо це давнє), атрибут даних data-someAttributeнедійсний; на специфікацію, дозволено використовувати лише малі літери. Ви зіткнетеся з безліччю дивних проблем, використовуючи великі регістри.
кен

1
Посилання на @AdrienBe Lot легко знайти за допомогою пошуку, але, оскільки мені нудно, ось тут: stackoverflow.com/a/22753630/84473
ken

Відповіді:


748

Якщо ви передаєте дані до DOM-елемента з сервера, вам слід встановити дані на елементі:

<a id="foo" data-foo="bar" href="#">foo!</a>

Потім можна отримати доступ до даних, використовуючи .data()jQuery:

console.log( $('#foo').data('foo') );
//outputs "bar"

Однак, коли ви зберігаєте дані на вузлі DOM у jQuery з використанням даних, змінні зберігаються на об'єкті вузла . Це для розміщення складних об'єктів та посилань, оскільки зберігання даних про елемент вузла, оскільки атрибут може містити лише рядкові значення.

Продовжуючи мій приклад зверху:
$('#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

Крім того, умова іменування для атрибутів даних має трохи прихованого "gotcha":

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 і більше не аналізується на NumberjQuery 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

17
@vitorbal, в той час як це так, об'єкт , що повертається .data()буде НЕ мати дефіс набору форм, так $('#bar').data('foo-bar-baz')буде працювати, але $('#bar').data()['foo-bar-baz']не буде. Саме тому я пропоную людям уникати використання дефісів.
zzzzBov

1
ок, тепер я бачу, що ти маєш на увазі. Не знав про цю маленьку деталь, дякую за оновлення :)
vitorbal

1
@SableFoste, яке посилання? api.jquery.com/data є правильним посиланням для методу, і не змінився, наскільки мені відомо.
zzzzBov

1
мені подобається, foo, bar, baz, fizz, buzz більше: D
Usman Younas

1
Любіть кожен рядок.
Foo Bar

108

Основна відмінність між ними полягає в тому, де вона зберігається та як до неї доступ.

$.fn.attr зберігає інформацію безпосередньо про елемент в атрибутах, які є загальнодоступними при огляді, а також доступні з власного API елемента.

$.fn.dataзберігає інформацію в смішно незрозумілому місці. Він розташований у закритій над локальною змінною, data_userяка називається екземпляром локально визначеної функції Data. Ця змінна недоступна за межами jQuery безпосередньо.

Набір даних за допомогою attr()

  • доступний з $(element).attr('data-name')
  • доступний з element.getAttribute('data-name'),
  • якщо значення було у вигляді data-nameтакож доступного з $(element).data(name)і element.dataset['name']таelement.dataset.name
  • видно на елементі при огляді
  • не можуть бути об'єктами

Набір даних за допомогою .data()

  • доступний лише з.data(name)
  • недоступний ні з .attr()іншого місця
  • не є загальнодоступним на елементі при огляді
  • можуть бути об’єкти

2
Так, моє головне питання було де зберігати ці дані, тож дякую за цю інформацію!
Макс Уайлдер

2
Крім того, .attr()це шлях, якщо згодом ви хочете використовувати дані в якості селектора ( .data()не буде знайдений, см codepen.io/anon/pen/EvawPV?editors=1011 )
Kamafeather

1

Ви можете використовувати data-*атрибут для вставки спеціальних даних. Ці data-*атрибути дають нам можливість вбудовувати свої атрибути даних на всіх HTML - елементах.

.data()Метод jQuery дозволяє отримувати / встановлювати дані будь-якого типу до елементів DOM таким чином, щоб бути захищеним від кругових посилань і, отже, від витоків пам'яті.

.attr()Метод jQuery get / set значення атрибута get / set лише для першого елемента зіставленого набору.

Приклад:

<span id="test" title="foo" data-kind="primary">foo</span>

$("#test").attr("title");
$("#test").attr("data-kind");
$("#test").data("kind");
$("#test").data("value", "bar");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.