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

736

У меня есть следующий сценарий:

var el = 'li';

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

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

До сих пор мои попытки не увенчались успехом, пытаясь построить селектор, который будет соответствовать текущему слайду:

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

не соответствует/не возвращает ничего...

Причина, по которой я не могу выполнить hardcode li, состоит в том, что это переменная, доступная пользователю, которая может быть изменена на другой элемент, если это необходимо, поэтому не всегда может быть li.

Любые идеи о том, что мне не хватает?

  • 6
    Вы уверены, что внутри .find(el+[data-slide=+current+]); это код, который вы пишете? кажется, вы пропустили некоторые цитаты из "[data-slide]"
Теги:
jquery-selectors
custom-data-attribute

8 ответов

1057
Лучший ответ

Вы должны ввести значение current в селектор Атрибуты атрибутов:

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

Способ ES6:

$("ul").find(`[data-slide='${current}']`)
  • 1
    Я должен был сделать это несколько раз прежде ... было бы хорошо, если бы у них была функция для этого. Я думаю, что я добавлю это в #query ...
  • 2
    Хороший, теперь еще один вопрос в более общем смысле. Хотя сейчас это прекрасно работает для моего примера, есть ли способ, которым я могу привести свою переменную el в нечто подобное? или это будет просто $("ul").find("+el+"[data-slide='" + current +"']"); ;?
Показать ещё 20 комментариев
370

если вы не хотите вводить все это, здесь более короткий способ запроса по атрибуту data:

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

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

  • 24
    Для тех из вас, кому это небезразлично, учитывая структуру <ul><li data-slide="item"></li></ul> этот селектор ответа вернет undefined, поэтому он не работает в зависимости от сценария пользователя. Этот ответ будет работать для структуры <ul data-slide="item"><li></li></ul> Хотя я понимаю, почему его популярность объясняется краткостью, технически это неправильный ответ. jsfiddle.net/py5p2abL/1
  • 3
    Не забудьте рассматривать это как массив. Используйте [0] для доступа к первому найденному элементу.
Показать ещё 2 комментария
180

При поиске с помощью [data-x =...], обратите внимание, он не работает с jQuery.data(..) setter:

$('<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
30

Я улучшил на расшифровку filterByData для pso-html в 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

// test data
function extractData() {
  log('data-prop=val ...... ' + $('div').filterByData('prop', 'val').length);
  log('data-prop .......... ' + $('div').filterByData('prop').length);
  log('data-random ........ ' + $('div').filterByData('random').length);
  log('data-test .......... ' + $('div').filterByData('test').length);
  log('data-test=anyval ... ' + $('div').filterByData('test', 'anyval').length);
}

$(document).ready(function() {
  $('#b5').data('test', 'anyval');
});

// the actual extension
(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);


//just to quickly log
function log(txt) {
  if (window.console && console.log) {
    console.log(txt);
    //} else {
    //  alert('You need a console to check the results');
  }
  $("#result").append(txt + "<br />");
}
#bPratik {
  font-family: monospace;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="bPratik">
  <h2>Setup</h2>
  <div id="b1" data-prop="val">Data added inline :: data-prop="val"</div>
  <div id="b2" data-prop="val">Data added inline :: data-prop="val"</div>
  <div id="b3" data-prop="diffval">Data added inline :: data-prop="diffval"</div>
  <div id="b4" data-test="val">Data added inline :: data-test="val"</div>
  <div id="b5">Data will be added via jQuery</div>
  <h2>Output</h2>
  <div id="result"></div>

  <hr />
  <button onclick="extractData()">Reveal</button>
</div>

Или скрипка: http://jsfiddle.net/PTqmE/46/

18

Я столкнулся с такой же проблемой при извлечении элементов с использованием атрибута 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.
  • 1
    Лучший ответ. Спасибо
  • 0
    Согласен. Лучший ответ на 2019 год. Давайте двигаться дальше.
8

Возвращаясь к исходному вопросу о том, как сделать эту работу, не зная тип элемента заранее, следующее:

$(ContainerNode).find(el.nodeName + "[data-slide='" + current + "']");
6

Этот селектор $("ul [data-slide='" + current +"']"); будет работать для следующей структуры:

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

Пока этот $("ul[data-slide='" + current +"']"); будет работать для:

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

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

Я надеюсь, что это может работать лучше

спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню