用于普通javascript对象的jquery选择器而不是DOM元素

bre*_*dan 6 javascript jquery css-selectors

我刚刚开始使用jquery,我真的很喜欢使用选择器.在我看来,成语将是一种非常好的遍历对象树的方法(例如,JSON查询结果).例如,如果我有这样的对象:

var obj = { 'foo': 1, 'bar': 2,
            'child': { 'baz': [3, 4, 5] }
          };
Run Code Online (Sandbox Code Playgroud)

我希望能够写出像$('child baz:last',obj)这样的东西并得到5.我认识到链接不起作用,但我仍然喜欢选择算子.任何人都知道这样的野兽是否存在,或者写一个最简单的方法是什么?

Ate*_*ral 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));
}
Run Code Online (Sandbox Code Playgroud)

用法是:

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");
Run Code Online (Sandbox Code Playgroud)

给出输出:

Selector: child baz
- Found: 3,4,5
Selector: bar
- Found: 2
- Found: [object Object]
- Found: 3

当然,除了上述内容之外,您还必须实现更多功能,以支持更复杂的选择器.

顺便说一句,你见过jLinq吗?