Селектор данных jquery
Мне нужно выбрать элементы на основе значений, хранящихся в объекте .data()
элемента. Как минимум, я хотел бы выбрать свойства данных верхнего уровня с помощью селекторов, возможно, так:
$('a').data("category","music"); $('a:data(category=music)');
Или, возможно, селектор будет в регулярном формате выбора атрибутов:
$('a[category=music]');
Или в формате атрибута, но со спецификатором, чтобы указать, что он находится в .data()
:
- jQuery scrollTop не работает в Chrome, но работает в Firefox
- jQuery: выбрать class элемента и идентификатор одновременно?
- Получить список отмеченных флажков в div с помощью jQuery
- addID в jQuery?
- jQuery как найти элемент на основе значения атрибута данных?
$('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? Моя озабоченность связана прежде всего с производительностью, но также и с дополнительными функциями, такими как точечное обозначение субсайта и несколько селекторов данных. Существуют ли другие реализации, которые поддерживают эти вещи или чем-то лучше?
- поиск jQuery и контекст
- Является ли jQuery каким-либо кэшированием «селекторов»?
- Включение / выключение флажков
- Доступ к css ": после" селектор с jQuery
- Должны ли все события jquery быть привязаны к $ (документу)?
- jQuery hasClass () - проверьте несколько classов
- Выбрать элемент по точному соответствию его содержимому
- Как работают PrimeFaces Selectors как в update = "@ (. MyClass)"?
Я создал новый селектор 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