Селектор данных jquery

Мне нужно выбрать элементы на основе значений, хранящихся в объекте .data() элемента. Как минимум, я хотел бы выбрать свойства данных верхнего уровня с помощью селекторов, возможно, так:

 $('a').data("category","music"); $('a:data(category=music)'); 

Или, возможно, селектор будет в регулярном формате выбора атрибутов:

 $('a[category=music]'); 

Или в формате атрибута, но со спецификатором, чтобы указать, что он находится в .data() :

 $('a[:category=music]'); 

Я нашел реализацию Джеймса Падолси, чтобы выглядеть просто, но все же хорошо. Селектор форматирует выше методы зеркала, показанные на этой странице. Существует также этот патч Sizzle .

По какой-то причине я вспоминаю некоторое время назад, что jQuery 1.4 будет включать поддержку селекторов по значениям в объекте jquery .data() . Однако теперь, когда я ищу его, я не могу его найти. Возможно, это был просто запрос функции, который я видел. Есть ли поддержка для этого, и я просто не вижу его?

В идеале я хотел бы поддерживать под-свойства в data (), используя точечную нотацию. Как это:

 $('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"}); $('a[:user.name.first=Tom]'); 

Я также хотел бы поддерживать несколько селекторов данных, в которых найдены только элементы со всеми указанными селекторами данных. Регулярный множественный селектор jquery выполняет операцию ИЛИ. Например, $('a.big, a.small') выбирает tags с big или small classом). Я ищу И, возможно, так:

 $('a').data("artist",{id: 3281, name: "Madonna"}); $('a').data("category","music"); $('a[:category=music && :artist.name=Madonna]'); 

Наконец, было бы здорово, если бы операторы сравнения и регулярные выражения были доступны в селекторах данных. Таким образом, возможно $(a[:artist.id>5000]) . Я понимаю, что, вероятно, мог бы сделать большую часть этого с помощью filter() , но было бы неплохо иметь простой формат селектора.

Какие решения доступны для этого? На данный момент лучшим решением является Jame’s Padolsey? Моя озабоченность связана прежде всего с производительностью, но также и с дополнительными функциями, такими как точечное обозначение субсайта и несколько селекторов данных. Существуют ли другие реализации, которые поддерживают эти вещи или чем-то лучше?

Я создал новый селектор data , который должен позволить вам выполнять вложенные запросы и условия И. Применение:

 $('a:data(category==music,artist.name==Madonna)'); 

Шаблон:

 :data( {namespace} [{operator} {check}] ) 

«оператор» и «проверка» являются необязательными. Итак, если у вас есть только :data(abc) он просто проверяет правдоподобие abc .

Вы можете увидеть доступных операторов в приведенном ниже коде. Среди них ~= что позволяет проводить регулярное тестирование:

 $('a:data(category~=^mus..$,artist.name~=^M.+a$)'); 

Я тестировал его с несколькими вариантами, и, похоже, он работает неплохо. Я, вероятно, добавлю это как рефинансирование Github в ближайшее время (с полным набором тестов), так что следите!

Код:

 (function(){ var matcher = /\s*(?:((?:(?:\\\.|[^.,])+\.?)+)\s*([!~><=]=|[><])\s*("|')?((?:\\\3|.)*?)\3|(.+?))\s*(?:,|$)/g; function resolve(element, data) { data = data.match(/(?:\\\.|[^.])+(?=\.|$)/g); var cur = jQuery.data(element)[data.shift()]; while (cur && data[0]) { cur = cur[data.shift()]; } return cur || undefined; } jQuery.expr[':'].data = function(el, i, match) { matcher.lastIndex = 0; var expr = match[3], m, check, val, allMatch = null, foundMatch = false; while (m = matcher.exec(expr)) { check = m[4]; val = resolve(el, m[1] || m[5]); switch (m[2]) { case '==': foundMatch = val == check; break; case '!=': foundMatch = val != check; break; case '<=': foundMatch = val <= check; break; case '>=': foundMatch = val >= check; break; case '~=': foundMatch = RegExp(check).test(val); break; case '>': foundMatch = val > check; break; case '<': foundMatch = val < check; break; default: if (m[5]) foundMatch = !!val; } allMatch = allMatch === null ? foundMatch : allMatch && foundMatch; } return allMatch; }; }()); 

На данный момент я выбираю так:

 $('a[data-attribute=true]') 

Кажется, что все работает нормально, но было бы неплохо, если бы jQuery смог выбрать этот атрибут без префикса ‘data-‘.

Я не тестировал это с данными, добавленными к элементам через jQuery динамически, так что это может быть падение этого метода.

Вы также можете использовать простую функцию фильтрации без каких-либо плагинов. Это не совсем то, что вы хотите, но результат тот же:

 $('a').data("user", {name: {first:"Tom",last:"Smith"},username: "tomsmith"}); $('a').filter(function() { return $(this).data('user') && $(this).data('user').name.first === "Tom"; }); 

Я хочу предупредить вас, что $('a[data-attribute=true]') не работает в соответствии с ответом Эшли, если вы привязали данные к элементу DOM с помощью функции data ().

Он работает так, как вы ожидали бы, добавив фактический data-attr в свой HTML, но jQuery хранит данные в памяти, поэтому результаты, которые вы получите от $('a[data-attribute=true]') , не будут быть верным.

Вам нужно будет использовать плагин данных http://code.google.com/p/jquerypluginsblog/ , использовать filter решение Dmitri или выполнить $ .each по всем элементам и проверить .data () итеративно

Есть плагин :data() который делает именно это 🙂

Некоторые примеры, основанные на вашем вопросе:

 $('a:data("category=music")') $('a:data("user.name.first=Tom")'); $('a:data("category=music"):data("artist.name=Madonna")'); //jQuery supports multiple of any selector to restrict further, //just chain with no space in-between for this effect 

Производительность не будет чрезвычайно велика по сравнению с тем, что возможно , выбор из $._cache и захват соответствующих элементов на сегодняшний день является самым быстрым, но гораздо более круглым и не очень «jQuery-ey» с точки зрения того, как вы получаете материал (вы обычно приходите со стороны элемента). Из моей головы я не уверен, что это так быстро, так как процесс перехода от уникального идентификатора к элементу запутан сам по себе с точки зрения производительности.

Селектор сравнения, о котором вы упоминали, будет лучше всего делать в .filter() , в этом плагине нет встроенной поддержки, хотя вы можете добавить его без особых проблем.

Вы можете установить атрибут data-* на вязах с помощью attr() , а затем выбрать с помощью этого атрибута:

 var elm = $('a').attr('data-test',123); //assign 123 using attr() elm = $("a[data-test=123]"); //select elm using attribute 

и теперь для этого вяза оба attr() и data() будут давать 123 :

 console.log(elm.attr('data-test')); //123 console.log(elm.data('test')); //123 

Однако, если вы измените значение, равное 456, используя attr() , data() будет по-прежнему 123 :

 elm.attr('data-test',456); //modify to 456 elm = $("a[data-test=456]"); //reselect elm using new 456 attribute console.log(elm.attr('data-test')); //456 console.log(elm.data('test')); //123 

Как я понимаю, похоже, что вам, вероятно, следует избегать смешивания команд attr() и data() в вашем коде, если вам это не нужно. Поскольку attr() видимому, напрямую соответствует DOM, тогда как data() взаимодействует с «памятью», хотя его начальное значение может быть из DOM. Но главное в том, что они не обязательно синхронизированы вообще.

Так что будьте осторожны.

Во всяком случае, если вы не изменяете атрибут data-* в DOM или в памяти, тогда у вас не будет проблемы. Вскоре, когда вы начнете изменять значения, возникают потенциальные проблемы.

Спасибо @Clarence Лю на @ Ash’s ответ, а также этот пост .

 $('a[data-category="music"]') 

Оно работает. См. Селектор выбора атрибутов [name = “value”] .

Если вы также используете jQueryUI, вы получаете (простую) версию :data селектора :data с ней, которая проверяет наличие элемента данных, поэтому вы можете сделать что-то вроде $("div:data(view)") или $( this ).closest(":data(view)") .

См. http://api.jqueryui.com/data-selector/ . Я не знаю, как долго они были у него, но он есть сейчас!

Вот плагин, который упрощает жизнь https://github.com/rootical/jQueryDataSelector

Используйте его так:

 data selector jQuery selector $$('name') $('[data-name]') $$('name', 10) $('[data-name=10]') $$('name', false) $('[data-name=false]') $$('name', null) $('[data-name]') $$('name', {}) Syntax error 
  • Как получить доступ к свойствам стиля псевдоэлементов с помощью jQuery?
  • Почему мой jQuery: not () не работает в CSS?
  • Что такое fastest children () или find () в jQuery?
  • Выбор индекса jQuery
  • Подстановочные знаки в селекторах jQuery
  • Элемент или class LIKE для jQuery?
  • jQuery или CSS-селектор, чтобы выбрать все идентификаторы, начинающиеся с некоторой строки
  • Селектор jQuery для метки флажка
  • Более чистый способ выбора нескольких возможных значений атрибутов?
  • Разница между CSS-селектором и фильтром jQuery?
  • jQuery: исключить $ (this) из селектора
  • Давайте будем гением компьютера.