How to use jQuery selector/find() against text string without inserting into the DOM?

6.6k Views Asked by At

I have a text string i'm trying to select the spans from using jQuery. I'd like to grab the spans w/o adding the element to the dom -- if that's possible?

After reading the jquery docs i was under the assumption that i could create a fragment by wrapping the string in a jquery selector tag, then using.find() to find the elements i want.

I have code that is similar to this but from the looks of the last line, it's obvious that no spans are being selected; any help would be greatly appreciated:

// 'text' is normally generated automatically... 
// just made it an escaped string for example purposes.
var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).find('span');
console.log(text); // => <span id="blah1">Y</span><br/><span id="blah2">o</span><br/>
console.log(spans.length); // => 0 

Thanks.

2

There are 2 best solutions below

4
On BEST ANSWER

You want to use filter(), not find()

var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).filter('span');
console.log(spans.length);

jsFiddle

From the jQuery docs

filter:

The supplied selector is tested against each element; all elements matching the selector will be included in the result.

find:

the .find() method allows us to search through the descendants of these elements in the DOM tree and construct a new jQuery object from the matching elements.

with your html fragment, there is no wrapper element, so there is no descendants, hence why find() does not work.

You are basically doing:

var elems = jQuery("<span id=\"blah1\">Y</span>").add("<br/>").add("<span id=\"blah2\">o</span>").add("<br/>");

If you want find to work with find(), you need to wrap it in an element.

var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>"; 
var spans = jQuery("<div></div>").append(text).find("span");
console.log(spans.length);
0
On

You want to use filter in this case:

var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $(text).filter('span');
console.log(spans.length); // 2

Demo: http://jsfiddle.net/ambiguous/TGY3J/

Or wrap it in a <div> and use find:

var text ="<span id=\"blah1\">Y</span><br/><span id=\"blah2\">o</span><br/>";
var spans = $('<div>' + text + '</div>').find('span');
console.log(spans.length); // 2

Demo: http://jsfiddle.net/ambiguous/qbCjk/

find works on descendants but without the <div> wrapper, your $(text) doesn't have any <span> descendants. Wrapping your HTML in a <div> is probably your best bet, that way you don't have to worry about how deep your desired elements are.