Вибір елемента за атрибутом даних


1019

Чи існує простий і прямий метод вибору елементів на основі їх dataатрибута? Наприклад, виберіть усі якір, який має атрибут даних, customerIDякий має значення 22.

Я якось вагаюся використовувати relчи інші атрибути для зберігання такої інформації, але мені набагато важче вибрати елемент на основі того, які дані зберігаються в ньому.


2
Дивіться також stackoverflow.com/q/4191386/292060
goodeye

Ось що мені допомогло вибрати всі атрибути даних (незалежно від значення): $('*[data-customerID]')Ви можете використовувати їх, наприклад,$('*[data-customerID]').each( function() { ... });
Кай Ноак

Відповіді:


1467
$('*[data-customerID="22"]');

Ви можете мати можливість пропустити *, але якщо я пам'ятаю правильно, залежно від того, яку версію jQuery ви використовуєте, це може дати несправні результати.

Зауважте, що для сумісності з API Selectors ( document.querySelector{,all}), лапки навколо значення атрибута ( 22) в цьому випадку можуть не бути опущені .

Крім того, якщо ви багато працюєте з атрибутами даних у своїх сценаріях jQuery, можливо, ви захочете скористатися плагіном спеціальних атрибутів даних HTML5 . Це дозволяє записати ще більше читабельний код за допомогою використання .dataAttr('foo')та призводить до зменшення розміру файлу після мінімізації (порівняно з використанням .attr('data-foo')).


69
Лише зауважте, що .data ('foo') працює, щоб отримати значення атрибуту 'data-foo', починаючи з jQuery 1.4.3. Крім того, оскільки jQuery 1.6: .data ('fooBar') отримує атрибут 'data-foo-bar'.
Джеймс Маккормак

4
@Zootius: Так, у програмі readme плагіна є примітка про це: "Станом на jQuery 1.4.3, .data()картки налаштовуються на власні data-*атрибути за замовчуванням, що робить цей плагін зайвим. Він все ще може використовуватися для старих версій jQuery. "
Mathias Bynens

То як один пост jQuery 1.4.3 вибирає об'єкт за значенням його об'єкта даних? Давайте II хотів би вибрати в цьому прикладі будь-який об’єкт із даними для ID клієнта, рівним 22?
Поїздка

54
Також якщо вас цікавить лише наявність конкретного атрибута даних, ви можете зробити це:$('[data-customerID]')
Darkside

7
Це не працює, якщо поле даних було встановлено jquery (використовуючи .data()), правда?
Мартін Р.

329

Люди гуглить і хочуть більш загальні правила щодо вибору з атрибутами даних:

$("[data-test]")вибере будь-який елемент, який має лише атрибут даних (незалежно від значення атрибута). У тому числі:

<div data-test=value>attributes with values</div>
<div data-test>attributes without values</div>

$('[data-test~="foo"]')вибере будь-який елемент, де міститься атрибут даних, fooале не повинен бути точним, наприклад:

<div data-test="foo">Exact Matches</div>
<div data-test="this has the word foo">Where the Attribute merely contains "foo"</div>

$('[data-test="the_exact_value"]')вибере будь-який елемент, у якому точне значення атрибута даних the_exact_value, наприклад:

<div data-test="the_exact_value">Exact Matches</div>

але не

<div data-test="the_exact_value foo">This won't match</div>

21
Добре. Зауважте, що ~=відповідає словам, розділеним пробілом, тоді як *=відповідає будь-якій підрядковій рядку
сам

Що з ^персонажем?
kuba44

1
@ kuba44 дійсно ви також можете використовувати ^, оскільки $('[data-test^=foo]')в такому випадку ви вибираєте все, що починається з foo, наприклад, <div data-test="foo_exact_value">чи <div data-test="food">ні<div data-test="seafoo">
JDuarteDJ

Повний список селекторів атрибутів: drafts.csswg.org/selectors-3/#attribute-selectors
користувач1460043

142

Використання $('[data-whatever="myvalue"]')вибере що-небудь з атрибутами html, але в новіших jQueries здається, що якщо ви використовуєте $(...).data(...)для вкладення даних, він використовує якийсь магічний браузер, який не вдається і не впливає на html, тому не виявляється, .findяк зазначено в попередній відповіді .

Перевірте (тестовано з 1.7.2+) (також дивіться скрипку ): (оновлено, щоб бути більш повним)

var $container = $('<div><div id="item1"/><div id="item2"/></div>');

// add html attribute
var $item1 = $('#item1').attr('data-generated', true);

// add as data
var $item2 = $('#item2').data('generated', true);

// create item, add data attribute via jquery
var $item3 = $('<div />', {id: 'item3', data: { generated: 'true' }, text: 'Item 3' });
$container.append($item3);

// create item, "manually" add data attribute
var $item4 = $('<div id="item4" data-generated="true">Item 4</div>');
$container.append($item4);

// only returns $item1 and $item4
var $result = $container.find('[data-generated="true"]');

1
аха - виявляється, хто - то ще це вказує на stackoverflow.com/questions/4191386 / ...
drzaus

4
і пропонує рішення .filter тут
drzaus

22
він використовує якийсь магічний браузер, який не є важливим і не впливає на html : немає такої речі, як магія;) learningjquery.com/2011/09/using-jquerys-data-apis
Том Сардуй


1
Якщо ви додаєте атрибут даних, який потрібно знайти пізніше, використовуйте$item.attr('data-id', 10);
Педро Морейра,

77

Я не бачив відповіді на JavaScript без jQuery. Сподіваємось, це комусь допомагає.

var elements = document.querySelectorAll('[data-customerID="22"]');

elements[0].innerHTML = 'it worked!';
<a data-customerID='22'>test</a>

Інформація:


1
Дякую за це Приємно бачити рішення, що не відповідають питанням.
Чак

68

Для вибору всіх якорів з атрибутом даних data-customerID==22слід включити aобмеження сфери пошуку лише на цей тип елемента. Пошуки атрибутів даних у великому циклі або на високій частоті, коли на сторінці багато елементів, можуть спричинити проблеми з продуктивністю.

$('a[data-customerID="22"]');

27

Рідні приклади JS

Отримайте NodeList елементів

var elem = document.querySelectorAll('[data-id="container"]')

html: <div data-id="container"></div>

Отримайте перший елемент

var firstElem = document.querySelector('[id="container"]')

html: <div id="container"></div>

Націліть на набір вузлів, який повертає ноделіст

document.getElementById('footer').querySelectorAll('[data-id]')

html:

<div class="footer">
    <div data-id="12"></div>
    <div data-id="22"></div>
</div>

Отримуйте елементи на основі кількох значень даних (АБО)

document.querySelectorAll('[data-section="12"],[data-selection="20"]')

html:

<div data-selection="20"></div>
<div data-section="12"></div>

Отримуйте елементи на основі комбінованих значень даних (AND)

document.querySelectorAll('[data-prop1="12"][data-prop2="20"]')

html:

<div data-prop1="12" data-prop2="20"></div>

Отримати елементи, з яких починається значення

document.querySelectorAll('[href^="https://"]')

Селектор для "отримати перший елемент" правильний, але не відповідає іншим прикладам - ​​я вважаю, що у нього відсутні "дані-".
GuyPaddock

15

методом Jquery filter ():

http://jsfiddle.net/9n4e1agn/1/

HTML:

<button   data-id='1'>One</button>
<button   data-id='2'>Two</button>

JavaScript:

$(function() {    
    $('button').filter(function(){
        return $(this).data("id")   == 2}).css({background:'red'});  
     });

Ви спробували скрипку? Метод FIlter - це лише інший підхід для досягнення того самого. Це може бути корисно, коли у вас вже є набір об’єктів Jquery і вам потрібно фільтрувати на основі атрибутів даних або чого-небудь іншого.
Разан Пол

Мої вибачення, @ Blizzard. Я прокоментував неправильну відповідь. Вставте його праворуч зараз. #AlwaysALongDayAtWork
Петро Єпископ

15

Така конструкція: $('[data-XXX=111]')не працює в Safari 8.0 .

Якщо ви встановили дані пояснюють це так: $('div').data('XXX', 111)він працює тільки якщо встановити атрибут даних безпосередньо в DOM так: $('div').attr('data-XXX', 111).

Я думаю, що це тому, що команда jQuery оптимізувала збір сміття для запобігання витоку пам’яті та важких операцій по відновленню DOM за кожним атрибутом зміни даних.


Це мені дуже допомогло - якщо я використовував дані або методи опори, то виділення за допомогою $ ('... [data-x = "y"]') не працювало - замість цього я використовував attr (це змінює атрибут на ДОМ). Thx
Jarda

13

Щоб це працювало в Chrome, значення не повинно мати іншої пари лапок.

Це працює лише, наприклад, так:

$('a[data-customerID=22]');

4
Це здається неправильним. Принаймні, це невірно зараз. Я щойно використав $ ('[data-action = "setStatus"]'). DeleteClass ('вимкнено'); в Chrome, і він працює чудово.
Петро Єпископ

Я думаю, що немає "" всередині селектора, він може бути використаний як$('[data-action=setStatus]').removeClass('disabled')
Анімеш Сінгх,

6

Іноді бажано фільтрувати елементи, виходячи з того, чи є в них програмні файли, приєднані до них програмно (так само не через dom-атрибути):

$el.filter(function(i, x) { return $(x).data('foo-bar'); }).doSomething();

Вищезазначене працює, але не дуже читабельно. Кращим підходом є використання псевдоселектора для тестування подібних речей:

$.expr[":"].hasData = $.expr.createPseudo(function (arg) {
    return function (domEl) {
        var $el = $(domEl);
        return $el.is("[" + ((arg.startsWith("data-") ? "" : "data-") + arg) + "]") || typeof ($el.data(arg)) !== "undefined";
    };
});

Тепер ми можемо переробити оригінальну заяву на щось більш вільне і читабельне:

$el.filter(":hasData('foo-bar')").doSomething();

1
У першому рішенні пропущений оператор return, він повинен бути: $ el.filter (функція (i, x) {return $ (x) .data ('foo-bar');}). DoSomething ();
Сальма Гомаа

3

Просто щоб доповнити всі відповіді деякими особливостями «життєвого рівня» - На сьогоднішній день (в епоху html5) це можна зробити без сторонньої версії:

  • чистий / простий JS з querySelector (використовує CSS-селектори):
    • виберіть першого в DOM: document.querySelector('[data-answer="42"],[type="submit"]')
    • вибрати всіх у DOM: document.querySelectorAll('[data-answer="42"],[type="submit"]')
  • чистий / простий CSS
    • деякі конкретні теги: [data-answer="42"],[type="submit"]
    • всі теги з певним атрибутом: [data-answer]абоinput[type]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.