2009-07-17 106 views
6

我剛開始使用jQuery,我非常喜歡使用選擇器。我發現這個習慣用法是遍歷對象樹的非常好的方法(例如,JSON查詢結果)。舉例來說,如果我有這樣的對象:jquery選擇器的純JavaScript對象,而不是DOM元素

var obj = { 'foo': 1, 'bar': 2, 
      'child': { 'baz': [3, 4, 5] } 
      }; 

我希望能夠寫類似$(「孩子巴茲:去年」,OBJ)並獲得5.我承認,鏈接不會工作,但我仍然喜歡選擇運算符。任何人都知道這樣的野獸是否存在,或者寫一個最簡單的方法是什麼?

+0

使用jQuery包裹的元素,然後循環正是在那裏,你不喜歡obj.child.baz理由[obj.child.baz.length -1]; ? – 2009-07-17 16:40:46

+0

對於這個玩具的例子來說,它可以工作,但是對於更深的樹木和更大的物體很快就會崩潰。例如,我正在研究一個使用樹代表網絡數據包的程序,並且我希望能夠編寫$('icmp [code = UNREACHABLE]'數據包列表)來獲取ICMP幀以供不可達數據包使用。 – brendan 2009-07-17 16:46:10

回答

5

這裏是一個概念驗證實現獲取jQuery本身的工作對象。通過對象包裝(FakeNode),你可以欺騙的jQuery到使用其內置的純JavaScript對象選擇器引擎(灒):

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

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); 
+0

謝謝。是的,這與我現在的工作有關。但在我看來,選擇器更強大,因爲您不必知道您正在走路的特定對象的確切形狀,以便找到有趣的元素。我認爲有一個很好的理由jQuery不會讓你做html.body.table [1] .tr ... – brendan 2009-07-17 16:52:09

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. 

在比賽的最後階段,我看不出這是非常有用的。但呃,這是一個想法,我猜=)

0

簡單,最簡單的方法是通過每個

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); 
} 
}); 
相關問題