jquery 数据选择器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2891452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery data selector
提问by Tauren
I need to select elements based on values stored in an element's .data()
object. At a minimum, I'd like to select top-level data properties using selectors, perhaps like this:
我需要根据元素.data()
对象中存储的值来选择元素。至少,我想使用选择器选择顶级数据属性,可能是这样的:
$('a').data("category","music");
$('a:data(category=music)');
Or perhaps the selector would be in regular attribute selector format:
或者选择器可能采用常规属性选择器格式:
$('a[category=music]');
Or in attribute format, but with a specifier to indicate it is in .data()
:
或者以属性格式,但带有说明符以指示它在.data()
:
$('a[:category=music]');
I've found James Padolsey's implementationto look simple, yet good. The selector formats above mirror methods shown on that page. There is also this Sizzle patch.
我发现James Padolsey 的实现看起来很简单,但很好。选择器格式高于该页面上显示的镜像方法。还有这个Sizzle 补丁。
For some reason, I recall reading a while back that jQuery 1.4 would include support for selectors on values in the jquery .data()
object. However, now that I'm looking for it, I can't find it. Maybe it was just a feature request that I saw. Is there support for this and I'm just not seeing it?
出于某种原因,我记得前一段时间读到 jQuery 1.4 将包含对 jquery.data()
对象中值的选择器的支持。然而,现在我正在寻找它,我找不到它。也许这只是我看到的一个功能请求。是否有支持,而我只是没有看到?
Ideally, I'd like to support sub-properties in data() using dot notation. Like this:
理想情况下,我想使用点表示法支持 data() 中的子属性。像这样:
$('a').data("user",{name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a[:user.name.first=Tom]');
I also would like to support multiple data selectors, where only elements with ALL specified data selectors are found. The regular jquery multiple selector does an OR operation. For instance, $('a.big, a.small')
selects a
tags with either class big
or small
). I'm looking for an AND, perhaps like this:
我还想支持多个数据选择器,其中只找到具有所有指定数据选择器的元素。常规的 jquery 多重选择器执行 OR 操作。例如,$('a.big, a.small')
选择a
带有 classbig
或small
) 的标签。我正在寻找一个 AND,可能是这样的:
$('a').data("artist",{id: 3281, name: "Madonna"});
$('a').data("category","music");
$('a[:category=music && :artist.name=Madonna]');
Lastly, it would be great if comparison operators and regex features were available on data selectors. So $(a[:artist.id>5000])
would be possible. I realize I could probably do much of this using filter()
, but it would be nice to have a simple selector format.
最后,如果数据选择器上有比较运算符和正则表达式功能,那就太好了。所以$(a[:artist.id>5000])
是有可能的。我意识到我可能可以使用 来做很多事情filter()
,但是拥有一个简单的选择器格式会很好。
What solutions are available to do this? Is Jame's Padolsey's the best solution at this time? My concern is primarily in regards to performance, but also in the extra features like sub-property dot-notation and multiple data selectors. Are there other implementations that support these things or are better in some way?
有哪些解决方案可以做到这一点?詹姆斯的帕多西是这个时候最好的解决方案吗?我关心的主要是性能,但也有额外的功能,比如子属性点符号和多个数据选择器。是否有其他实现支持这些东西或在某些方面更好?
采纳答案by James
I've created a new data
selector that should enable you to do nested querying and AND conditions. Usage:
我创建了一个新的data
选择器,它应该使您能够进行嵌套查询和 AND 条件。用法:
$('a:data(category==music,artist.name==Madonna)');
The pattern is:
图案是:
:data( {namespace} [{operator} {check}] )
"operator" and "check" are optional. So, if you only have :data(a.b.c)
it will simply check for the truthinessof a.b.c
.
“操作员”和“检查”是可选的。所以,如果你只有:data(a.b.c)
它会简单地检查了感实性的a.b.c
。
You can see the available operators in the code below. Amongst them is ~=
which allows regex testing:
您可以在下面的代码中看到可用的运算符。其中包括~=
允许正则表达式测试:
$('a:data(category~=^mus..$,artist.name~=^M.+a$)');
I've tested it with a few variations and it seems to work quite well. I'll probably add this as a Github repo soon (with a full test suite), so keep a look out!
我已经用一些变体对其进行了测试,它似乎工作得很好。我可能很快会将此添加为 Github 存储库(带有完整的测试套件),所以请注意!
The code:
编码:
(function(){
var matcher = /\s*(?:((?:(?:\\.|[^.,])+\.?)+)\s*([!~><=]=|[><])\s*("|')?((?:\|.)*?)|(.+?))\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;
};
}());
回答by Ash
At the moment I'm selecting like this:
目前我是这样选择的:
$('a[data-attribute=true]')
Which seems to work just fine, but it would be nice if jQuery was able to select by that attribute without the 'data-' prefix.
这似乎工作得很好,但如果 jQuery 能够在没有 'data-' 前缀的情况下通过该属性进行选择,那就太好了。
I haven't tested this with data added to elements via jQuery dynamically, so that could be the downfall of this method.
我还没有使用通过 jQuery 动态添加到元素的数据来测试这个,所以这可能是这个方法的失败。
回答by Dmitri
You can also use a simple filtering function without any plugins. This is not exactly what you want but the result is the same:
您还可以使用没有任何插件的简单过滤功能。这不完全是你想要的,但结果是一样的:
$('a').data("user", {name: {first:"Tom",last:"Smith"},username: "tomsmith"});
$('a').filter(function() {
return $(this).data('user') && $(this).data('user').name.first === "Tom";
});
回答by Clarence Liu
I want to warn you that $('a[data-attribute=true]')
doesn't work, as per Ashley's reply, if you attached data to a DOM element via the data() function.
我想警告您,$('a[data-attribute=true]')
根据 Ashley 的回复,如果您通过 data() 函数将数据附加到 DOM 元素,这将不起作用。
It works as you'd expect if you added an actual data-attr in your HTML, but jQuery stores the data in memory, so the results you'd get from $('a[data-attribute=true]')
would not be correct.
如果您在 HTML 中添加了实际的数据属性,它会按您的预期工作,但 jQuery 将数据存储在内存中,因此您从中获得的结果$('a[data-attribute=true]')
将不正确。
You'll need to use the data plugin http://code.google.com/p/jquerypluginsblog/, use Dmitri's filter
solution, or do a $.each over all the elements and check .data() iteratively
您需要使用数据插件http://code.google.com/p/jquerypluginsblog/,使用 Dmitri 的filter
解决方案,或者对所有元素执行 $.each 并反复检查 .data()
回答by Nick Craver
There's a :data()
filter pluginthat does just this :)
有一个:data()
过滤器插件可以做到这一点:)
Some examples based on your question:
基于您的问题的一些示例:
$('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
The performance isn't going to be extremely great compared to what's possible, selecting from $._cache
and grabbing the corresponding elements is by far the fastest, but a lot more round-about and not very "jQuery-ey" in terms of how you get to stuff (you usually come in from the element side). Of th top of my head, I'm not sure this is fastest anyway since the process of going from unique Id to element is convoluted in itself, in terms of performance.
与可能的情况相比,性能不会非常好,从$._cache
相应的元素中选择和抓取是迄今为止最快的,但就您如何获得而言,它更加迂回且不是很“jQuery-ey”东西(你通常从元素方面进来)。在我的头顶上,我不确定这是否是最快的,因为从唯一 Id 到元素的过程本身就很复杂,就性能而言。
The comparison selector you mentioned will be best to do in a .filter()
, there's no built-in support for this in the plugin, though you could add it in without a lot of trouble.
您提到的比较选择器最好在 a 中进行.filter()
,插件中没有对此的内置支持,尽管您可以轻松添加它。
回答by D.Tate
You can set a data-*
attribute on an elm using attr()
, and then select using that attribute:
您可以使用 设置data-*
榆树上的属性attr()
,然后使用该属性进行选择:
var elm = $('a').attr('data-test',123); //assign 123 using attr()
elm = $("a[data-test=123]"); //select elm using attribute
and now for that elm, both attr()
and data()
will yield 123:
现在对于榆树,都attr()
和data()
将产生123:
console.log(elm.attr('data-test')); //123
console.log(elm.data('test')); //123
However, if you modify the value to be 456using attr()
, data()
will still be 123:
但是,如果您使用将值修改为456attr()
,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
So as I understand it, seems like you probably should steer clear of intermingling attr()
and data()
commands in your code if you don't have to. Because attr()
seems to correspond directly with the DOM whereas data()
interacts with the 'memory', though its initial value can be from the DOM. But the key point is that the two are not necessarily in sync at all.
因此,据我所知,如果不需要,您似乎应该避免在代码中混合attr()
和data()
命令。因为attr()
似乎直接与 DOM 对应,而data()
与“内存”交互,尽管它的初始值可以来自 DOM。但关键是两者根本就不一定同步。
So just be careful.
所以要小心。
At any rate, if you aren't changing the data-*
attribute in the DOM or in the memory, then you won't have a problem. Soon as you start modifying values is when potential problems can arise.
无论如何,如果您不更改data-*
DOM 或内存中的属性,那么您不会有问题。一旦您开始修改值,就会出现潜在问题。
Thanks to @Clarence Liu to @Ash's answer, as well as this post.
感谢@Clarence Liu 对@Ash 的回答以及这篇文章。
回答by Jorge Orpinel
$('a[data-category="music"]')
It works. See Attribute Equals Selector [name=”value”].
有用。请参阅属性等于选择器 [name=”value”]。
回答by Paul
If you also use jQueryUI, you get a (simple) version of the :data
selector with it that checks for the presence of a data item, so you can do something like $("div:data(view)")
, or $( this ).closest(":data(view)")
.
如果您还使用 jQueryUI,您将获得一个(简单)版本的:data
选择器,用于检查数据项是否存在,因此您可以执行诸如$("div:data(view)")
, 或 之类的操作$( this ).closest(":data(view)")
。
See http://api.jqueryui.com/data-selector/. I don't know for how long they've had it, but it's there now!
请参阅http://api.jqueryui.com/data-selector/。我不知道他们拥有它多久了,但它现在就在那里!
回答by Rootical V.
Here's a plugin that simplifies life https://github.com/rootical/jQueryDataSelector
这是一个简化生活的插件https://github.com/rootical/jQueryDataSelector
Use it like that:
像这样使用它:
data selector jQuery selector
$$('name') $('[data-name]')
$$('name', 10) $('[data-name=10]')
$$('name', false) $('[data-name=false]')
$$('name', null) $('[data-name]')
$$('name', {}) Syntax error