jQuery як знайти елемент на основі значення атрибутів даних?


994

У мене такий сценарій:

var el = 'li';

а на сторінці - 5 <li>з кожним data-slide=numberатрибутом (число 1,2,3,4,5 відповідно) .

Тепер мені потрібно знайти активний номер слайда, який відображається на карті var current = $('ul').data(current);та оновлюється при кожній зміні слайда.

Поки мої спроби були невдалими, намагаючись побудувати селектор, який би відповідав поточному слайду:

$('ul').find(el+[data-slide=+current+]);

нічого не відповідає / не повертає ...

Причина, за якою я не можу жорстко кодувати liчастину, полягає в тому, що це доступна для користувача змінна, яку при необхідності можна змінити на інший елемент, тому це не завжди може бути an li.

Будь-які ідеї щодо того, що мені не вистачає?


6
Ви впевнені, що в .find(el+[data-slide=+current+]);коді є код, який Ви пишете? здається, ви пропустили деякі цитати до"[data-slide]"
xandy

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

Відповіді:


1481

Ви повинні ввести значення currentв селектор Attribute Equals :

$("ul").find(`[data-slide='${current}']`)

Для старих середовищ JavaScript ( ES5 та новіших версій ):

$("ul").find("[data-slide='" + current + "']"); 

8
@Jannis, ти міг би зробити $("ul").find(el + "[data-slide='" + current +"']");.
Фредерік Хаміді

7
@ c00lryguy, інтерфейс jQuery визначає один, а навколо є окремі реалізації . Схоже, спроби його додавання до jQuery Core були відхилені . Двічі .
Фредерік Хаміді

6
у цій відповіді на подібному дописі є приклад функції фільтра
drzaus

77
Я переживаю, що це не спрацює, якщо дані були додані за допомогою функції jQuery .data (...), оскільки це не завжди відображає атрибут, і в цей час використовується специфічний для браузера механізм зберігання даних. Ще одна причина, за якою я бажаю, щоб ядро ​​jQuery мала специфічний селектор даних.
AaronLS

77
Зауважте, що він не працює для елементів, для яких ви встановлюєте дані за допомогою $ ('# element'). Data ('some-att-name', value); але лише для тих, хто з твердим атрибутом. У мене ця проблема і змусити її працювати встановити дані, записавши атрибут безпосередньо $ ('# елемент'). Attr ('data-some-att-name', значення);
Pawel

463

якщо ви не хочете все це вводити, ось коротший спосіб запиту за атрибутом даних:

$("ul[data-slide='" + current +"']");

FYI: http://james.padolsey.com/javascript/a-better-data-selector-for-jquery/


31
Для тих, хто вам небайдужий, враховуючи структуру, <ul><li data-slide="item"></li></ul>цей селектор відповідей повернеться невизначеним, тому він не працює з урахуванням сценарію користувача. Ця відповідь буде працювати для структури <ul data-slide="item"><li></li></ul> Хоча я розумію, чому її популярність через стислість, це технічно неправильна відповідь. jsfiddle.net/py5p2abL/1
akousmata

4
Не забудьте ставитися до цього як до масиву. Використовуйте [0]для доступу до першого знайденого елемента.
Аміна Нурайні

Химерний побічний ефект ... цей метод спрацював, співставляючи елемент з атрибутом даних, коли .find("[data-attrib='value']")не працював. Я не знаю, чи були значення атрибутів даних, додані jQuery чи ні ...
помилка

1
Це не химерно, бо два відповіді роблять 2 різні речі. $.findспеціально знаходить нащадків цього елемента, але, використовуючи синтаксис фільтра в рядку селектора, буде просто фільтрувати результати.
Філ

227

Під час пошуку за допомогою даних [data-x = ...], будьте уважні , він не працює з сектором jQuery.data (..) :

$('<b data-x="1">'  ).is('[data-x=1]') // this works
> true

$('<b>').data('x', 1).is('[data-x=1]') // this doesn't
> false

$('<b>').attr('data-x', 1).is('[data-x=1]') // this is the workaround
> true

Ви можете використовувати це замість:

$.fn.filterByData = function(prop, val) {
    return this.filter(
        function() { return $(this).data(prop)==val; }
    );
}

$('<b>').data('x', 1).filterByData('x', 1).length
> 1

1
$.fn.filterByDataє блискучим; однак це попередження для копіювальних пастерів там ... вам потрібно лише $('<b>').filterByData('x', 1)знайти <b>теги data-x="1". якщо скопіювати та вставити .data(x, 1)частину ... ви встановите data-x"1" перед фільтруванням.
WEBjuju

39

Я покращився після розширення filterByData психо-Брм до jQuery.

Там, де попереднє розширення шукало на парі ключ-значення, за допомогою цього розширення ви можете додатково шукати наявність атрибута даних, незалежно від його значення.

(function ($) {

    $.fn.filterByData = function (prop, val) {
        var $self = this;
        if (typeof val === 'undefined') {
            return $self.filter(
                function () { return typeof $(this).data(prop) !== 'undefined'; }
            );
        }
        return $self.filter(
            function () { return $(this).data(prop) == val; }
        );
    };

})(window.jQuery);

Використання:

$('<b>').data('x', 1).filterByData('x', 1).length    // output: 1
$('<b>').data('x', 1).filterByData('x').length       // output: 1

Або скрипка: http://jsfiddle.net/PTqmE/46/


34

Без JQuery, ES6

document.querySelectorAll(`[data-slide='${current}']`);

Я знаю, що питання стосується JQuery, але читачі можуть захотіти чистого методу JS.


33

Я зіткнувся з тією ж проблемою, коли отримував елементи, використовуючи атрибут jQuery та data- *.

тож для довідки найкоротший код тут:

Це мій HTML-код:

<section data-js="carousel"></section>
<section></section>
<section></section>
<section data-js="carousel"></section>

Це мій селектор jQuery:

$('section[data-js="carousel"]');
// this will return array of the section elements which has data-js="carousel" attribute.


15

Цей селектор $("ul [data-slide='" + current +"']");буде працювати для наступної структури:

<ul><li data-slide="item"></li></ul>  

Хоча це $("ul[data-slide='" + current +"']");буде працювати для:

<ul data-slide="item"><li></li></ul>


12

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

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.