我刚刚开始使用jquery,我真的很喜欢使用选择器。在我看来,成语将是一种非常好的遍历对象树的方式(例如,JSON查询结果)。例如,如果我有这样的对象:
var obj = { 'foo': 1, 'bar': 2,
'child': { 'baz': [3, 4, 5] }
};
我希望能够写出像$('child baz:last',obj)这样的东西并得到5.我认识到链接不起作用,但我仍然喜欢选择运算符。有人知道这样的野兽是否存在,或者写一个最简单的方法是什么?
答案 0 :(得分:5)
这是一个概念验证实现,用于让jQuery本身在对象上工作。通过对象包装器(FakeNode
),您可以欺骗jQuery在纯JavaScript对象上使用其内置选择器引擎(Sizzle):
function FakeNode(obj, name, parent) {
this.obj = obj;
this.nodeName = name;
this.nodeType = name ? 1 : 9; // element or document
this.parentNode = parent;
}
FakeNode.prototype = {
documentElement: { nodeName: "fake" },
getElementsByTagName: function (tagName) {
var nodes = [];
for (var p in this.obj) {
var node = new FakeNode(this.obj[p], p, this);
if (p === tagName) {
nodes.push(node);
}
Array.prototype.push.apply(nodes,
node.getElementsByTagName(tagName));
}
return nodes;
}
};
function $$(sel, context) {
return $(sel, new FakeNode(context));
}
用法是:
var obj = {
foo: 1,
bar: 2,
child: {
baz: [ 3, 4, 5 ],
bar: {
bar: 3
}
}
};
function test(selector) {
document.write("Selector: " + selector + "<br>");
$$(selector, obj).each(function () {
document.write("- Found: " + this.obj + "<br>");
});
}
test("child baz");
test("bar");
给出输出:
Selector: child baz - Found: 3,4,5 Selector: bar - Found: 2 - Found: [object Object] - Found: 3
当然,为了支持更复杂的选择器,你必须实现更多以上的功能。
顺便说一句,你见过jLinq吗?答案 1 :(得分:0)
数组对象有一些可以使用的方法:
last = obj.child.baz.slice(-1)[0];
其他一些例子:
first = obj.child.baz.slice(0,1)[0];
allExceptFirst = obj.child.baz.slice(1);
allExceptLast = obj.child.baz.(0,-1);
答案 2 :(得分:0)
好吧,我个人说纯对象访问看起来比jQuery类查询更好。有一点可能是切片和其他过滤技术。
如果您真的想玩对象访问查询,以下是一些可能性(想想XPath):
var obj = {
foo: 1,
bar: 2,
child: {
foo: {
baz: [3, {a: 1}, {a: 2, b: 3}]},
bar: {
baz: [42, {a: 123}, {a: -1}]},
baz: null}};
// Implicitly start in the Global object, unless a context is provided.
// Keys in JavaScript objects are essentially stored in order (not valid for
// *all* flavors, but it's close to standard. So you could do slicing on keys.)
// Selects (does not return them)
// obj.child.foo.baz[1].a
// obj.child.foo.baz[2].a
// obj.child.bar.baz[1].a
// obj.child.bar.baz[2].a
// Then performs an aggregate that returns value 125.
$('obj.child[:2].baz[1:].a').sum()
// Selects obj.foo, obj.bar, obj.child.foo.baz[0] and obj.child.bar.baz[0]
$('obj *[typeof(number)]')
// Selects obj.foo and obj.child.foo
$('obj foo')
// Other possible methods: delete(), set(), get() (as an array of values),
// min(), max(), avg(), merge() etc etc.
最后,我不知道这是多么有用。但是,这是一个想法,我猜=)
答案 3 :(得分:0)
最简单,最简单的方法是用jquery包装元素,然后按每个
循环它var obj = { 'foo': 1, 'bar': 2,
'child': { 'baz': [3, 4, 5] }
};
$(obj).each(function(){
console.log(this);
if(this.hasOwnProperty('foo'))
{
console.log("hey i found " + this.foo );
}
});