tags:

views:

85

answers:

2

Why doesn't this work?

var string = '<b>Hello</b> this is just a <b>test</b>';
console.log($(string).find('b'));

I would expect Firebug's console to give me the two <b> elements, but instead I get an empty array.

However, if I change it to this:

var string = '<b>Hello</b> this is just a <b>test</b>';
console.log($('<div/>').html(string).find('b'));

It does what I want. I understand that jQuery internally assigns passed HTML it can't handle via createElement to a <div> element in order to parse it into a DOM structure, but shouldn't it be able to find elements in this passed HTML like I tried above? To make matters more confusing, sometimes I see people successfully using the first syntax when they get returned (and sometimes malformed) HTML from an AJAX request, but this never seems to work for me without manually appending my HTML to a <div>

What am I missing?

+1  A: 

In your first version, the jQuery object contains three nodes - a b tag, a text node, and a second b tag.

When you call find, it searches the children of these three nodes for b tags. Since none of the three nodes have any children, it doesn't find anything.

Your second version creates a single div tag with those three nodes inside of it. When you call find on it, it searches the div tag's children for b tags, which it finds.

If you call filter instead of find, it will search the nodes in the set. However, it won't find any b tags nested inside of other nodes in the set.

SLaks
A: 

It seems that when you do a creation of an element with just $(string), that jQuery is creating a jQuery object that contains three DOM items, effectively: the first bold tag, a text node, and the second bold tag. At that point, when you call .find on that, it looks inside each of those - and there's no nested bolding going on, so it finds nothing.

In a sense, it's really doing exactly what you're asking - you're giving it effectively three DOM pieces, and it parses it out into that, then calls find on each of those instead of some parent structure. :)

But then putting it all into a parent div, and searching the parent, you find what you're looking for.

Really, wrapping it all in a div is the safest way to work everything cross-browser.

Brian Arnold