0

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.

Mario Zigliotto
  • 8,315
  • 7
  • 52
  • 71
  • Why are you manipulating HTML as text? That's simply absurd. in-line HTML is the devil. – Raynos Nov 07 '11 at 02:36
  • Maybe it's an HTML string that is being returned from an AJAX call, or being created and returned from a template. ( I hope ) – bstakes Nov 07 '11 at 02:49
  • @bstakes ajax should never return HTML as a string. And templates should not return HTML they should return Nodes. – Raynos Nov 07 '11 at 02:54
  • The HTML is actually the result of a user selecting text on the page and I'm trying to select the elements that I "care" about. – Mario Zigliotto Nov 07 '11 at 03:17

2 Answers2

9

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);
epascarello
  • 204,599
  • 20
  • 195
  • 236
1

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.

mu is too short
  • 426,620
  • 70
  • 833
  • 800