Елемент фільтра на основі ключа / значення .data ()


116

Скажіть, у мене є 4 діва елементи з класом .navlink, які при натисканні використовуються .data()для встановлення виклику ключа 'selected', до значення true:

$('.navlink')click(function() { $(this).data('selected', true); })

Кожного разу при .navlinkнатисканні на нову я хотів би зберегти вибране раніше navlinkдля подальшої маніпуляції. Чи існує швидкий і простий спосіб вибрати елемент на основі того, що було збережено .data()?

Здається, не існує жодного jQuery : фільтри, які відповідають рахунку, і я спробував таке (у межах однієї події клацання), але чомусь це не працює:

var $previous = $('.navlink').filter( 
    function() { $(this).data("selected") == true }
);

Я знаю, що є й інші способи досягти цього, але зараз мені просто цікаво, чи можна це зробити через .data().

Відповіді:


192

ваш фільтр запрацював би, але вам потрібно повернути істину на відповідні об’єкти у функції, переданій у фільтр, щоб захопити їх.

var $previous = $('.navlink').filter(function() { 
  return $(this).data("selected") == true 
});

6
Зауважте, що це вже не єдиний спосіб зробити це, СтефаноП запропонував альтернативи
Натан Кооп,

3
@NathanKoop, не зовсім. Дивіться мій коментар до його відповіді.
Брайан Даунінг

Для тих, хто використовує атрибут даних, щоб знайти інакше незмінний елемент (id менше divs тощо), до якого потрібно мати доступ з будь-якої причини) в будь-якому місці документа:$("*").filter(function() { return $(this).data("DATA IDENTIFIER HERE") == DATA VALUE HERE; });
Tschallacka,

це не "безладно" - це єдиний безпечний спосіб фільтрації за довільними умовами, не вимагаючи, щоб ви "уникали" цих значень, щоб гарантувати, що з'єднання пошукового терміну з рештою селектора не створює незаконний вибір.
Альнітак

145

Тільки для запису, ви можете фільтрувати дані за допомогою jquery (це питання досить старе, і jQuery розвивався з того часу, тому правильно написати це рішення також):

$('.navlink[data-selected="true"]');

або, краще (для продуктивності):

$('.navlink').filter('[data-selected="true"]');

або, якщо ви хочете отримати всі елементи з data-selectedнабором:

$('[data-selected]')

Зауважте, що цей метод працюватиме лише з даними, встановленими через html-атрибути. Якщо встановити або змінити дані під час .data()виклику, цей спосіб більше не працюватиме.


9
якщо низький підрахунок голосів за цю відповідь вас лякає - це прийнята відповідь зі 100+ голосами на практично однакове запитання stackoverflow.com/questions/4146502
Simon_Weaver

48
-1 Це не працює, коли дані встановлюються .data()методом замість data-атрибута. Дивіться цю загадку : jsfiddle.net/bryandowning/tySWC - Також .find()метод шукає дітей попереднього селектора. У наведеному прикладі data-selectedє атрибутом .navlink, а не дитиною .navlink. Також, $('div p')і $('div').find('p')по суті є рівнозначними. Використання.find() здається, що це може бути повільніше через додатковий виклик функції (хоча я не позитивно ставлюсь до цього). Будь ласка, виправте мене, якщо я помиляюся з будь-яким із цього (я дуже хочу, щоб цей метод спрацював).
Брайан Даунінг

3
кілька речей: 1) Ви праві, що це не працює, якщо Ви встановлюєте дані .data(), оскільки jQuery здійснює пошук через DOM, я розміщував їх для тих (як я), які потрапили до цього питання з інших причин; 2) виправити, .find()шукати через дітей, тому в цьому прикладі це неправильно; 3) ви помиляєтеся, вони не рівнозначні, оскільки jQuery здійснює пошук справа наліво, див. Jonraasch.com/blog/…
StefanoP

2
Голосування за $('[data-selected]')це допомогло мені щось подібне$('ul.categories a[data-categories_id]').click(......);
Люк Двоюрідний

Крім того, здається, що якщо ви оновите атрибут даних за допомогою .attr, якщо ви отримаєте його за допомогою .data, значення не буде оновлено - тому будьте обережні при змішуванні двох
Fabio Lolli

13

Ми можемо зробити плагін досить легко:

$.fn.filterData = function(key, value) {
    return this.filter(function() {
        return $(this).data(key) == value;
    });
};

Використання (перевірка перемикача):

$('input[name=location_id]').filterData('my-data','data-val').prop('checked',true);

Ви маєте на увазі метод плагіна, інакше це те саме, що прийнятий відповідь ...
jave.web

@ jave.web Дійсно. Але не всі знають, як перетворити його на плагін. Оновлена ​​багатослівність.
mpen

Не зрозумійте мене неправильно, ваша відповідь великий, проте слова тут дуже важливо, спасибі за оновлення :)
jave.web

8

Я помітив дві речі (вони можуть бути помилками, коли ви це записали).

  1. Ви пропустили крапку в першому прикладі ( $('.navlink').click )
  2. Щоб фільтр працював, потрібно повернути значення ( return $(this).data("selected")==true)

-1

Здається, більше роботи, ніж її варті.

1) Чому б просто не мати єдиної змінної JavaScript, яка зберігає посилання на обраний на даний момент елемент \ jQuery об'єкт.

2) Чому б не додати клас до вибраного в даний момент елемента. Тоді ви можете запитати DOM для класу ".active" або щось подібне.


Так, але, як я вже говорив, я знав, що існують інші способи досягти цього. Мене просто застрягли, чи можна це відфільтрувати за допомогою даних (), і чому filter () не працює для мене. Спасибі, хоча.
користувач113716

Вибачте. Я пропустив ту частину вашого запитання.
Брайан Мігліорісі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.