I load up some HTML using $.get or $.ajax. In the debugger for both Chrome and Firefox i can see the html has been loaded properly:
> data
"<html><head><title></title></head><body>
<div id="topdiv" style="display:none;width:880px; height:600px;"></div>
</body</html>"
So it’s a string of HTML. Great. Next I try to use jQuery to parse it:
$doc = $(data);
> $doc
[<TextNode textContent="\n\n">,
title,
<TextNode textContent="\n\n\n">,
div#topdiv,
<TextNode textContent="\n \n">]
Whoah, what? Where did html, head, body go? OK, well anyway, all I care about is the div
$div = $data.find('div');
> $div
[]
Huh??
OK. The div is empty. Upon further experimentation, I realize that jQuery basically ignores any top-level tags. Then it doesn’t actually let you select any 2nd level tags, and so if there is a div nested inside the outer div, that WILL be selected. But… what??
Seems jQuery kind of chokes on those “TextNode” elements, that, curiously, it created itself (instead of html, body). So I wrote some code to get around this by looping through the elements, and extracting the non-text nodes directly:
function getNodes($doc) {
var result = new Array();
for (var i = 0; i < $doc.length; i++) {
if ($doc[i].hasOwnProperty("tagName")) {
result.push($doc[i]);
}
}
return $(result);
}
Worked great! On Chrome.
Tried it in Firefox, and nothing works again.
Turns out that not every object in Firefox has a hasOwnProperty function. WHAT?? Ok. So rewrite to this:
typeof($tempHtml[i].tagName) !== 'undefined'
Finally, works in Firefox too.
Wow. Am I just being stupid? Why is so much post processing needed just to turn a string of HTML into a jQuery object? I feel like I must be missing something obvious. Is there a way to do this that does not involve such mayhem?
All I am trying to do is load up some HTML and turn it into a jQuery object. Yet it seems to be an increasingly baffling ordeal. Am I just doing something fundamentally wrong? Why is this so complicated?
Read the jQuery documentation – it addresses this issue.
When you have a HTML string that contains
<html>,<head>, or<body>elements, and you do this:then those elements will be ignored. Only elements that can be put inside a DIV are valid and will be added to the resulting jQuery instance object.
This will result in an empty jQuery object because find() searches the descendants of the current set of elements (which is one TITLE element and one DIV element in your case – and those two elements don’t have descendant DIV elements).
In order to remove the Text Node objects from your jQuery object, I recommend this approach:
To get the DIV element, I recommend this approach:
where
stris your HTML string.Alternative approach: