Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the following jQuery selector not returning both elements?

I've run into a situation where I am creating a jQuery object from an html string and need to select all elements within it with a particular class.

What I'm finding odd is that its returning one or the other, depending on which type of selecting mechanism I'm using. A test case is shown here:

var tmpl = '<ul><li class="foo">TEST</li></ul><div class="foo">BAR</div>';

console.log( $('.foo', tmpl) ); //[<li class="foo">TEST</li>]
console.log( $(tmpl).find('.foo') ); //[<li class="foo">TEST</li>]
console.log( $(tmpl).filter('.foo') ); //[<div class="foo">BAR</div>]

http://jsfiddle.net/Rfq9F/

In this example, both an li element in a ul and a non-descendant div have the class "foo". In the example, I use the .foo selector and set context to the template string. Second, I use .find() on the string. Finally, I use .filter() on the string.

Can someone explain why the selector mechanisms are acting as they do, and also how to achieve the goal I mentioned in the beginning?

like image 686
Geuis Avatar asked Mar 13 '12 10:03

Geuis


2 Answers

It's because it's not a single root node, but two (ul and div).

Wrap everything in a <div> and it will work:

http://jsfiddle.net/Rfq9F/3/

like image 154
jgauffin Avatar answered Sep 28 '22 06:09

jgauffin


Calling $(tmpl) creates a set with two elements - the <ul> element and the <div class="foo"> element. .find() looks for elements that are descendents of any of the elements in the set that match the selector. .filter() returns any elements in the set that match the selector.

The first two lines:

console.log( $('.foo', tmpl) );
console.log( $(tmpl).find('.foo') );

are equivalent, they're just two different ways to write the same thing.

like image 20
Anthony Grist Avatar answered Sep 28 '22 06:09

Anthony Grist