2

I just discovered this issue, and I wanted to run it by everyone here to make sure I wasn't missing obvious something before I reported it.

Here is what's causing me a problem:

html = '<html><body><div id="test">This is just a test</div></body></html>';
alert( $(html).find('#test').html() );

The alert window shows null instead of the text inside #test. HOWEVER, if I simply wrap <div id="test"> in another div element, it works properly and returns the expected, "This is just a test".

This code works:

html = '<html><body><div><div id="test">This is just a test</div></div></body></html>';
alert( $(html).find('#test').html() );

Can someone explain to me why this would be happening? Why would the second example work but the first one not?

3 Answers 3

7

If you debug what $(html) does, you will notice it only creates the DOM tree for the “usefull” contents, here the div#test block (it strips the html and body containers). Thing is, find() looks for children of the element you're calling it from. As the root element of $(html) is already your div#test element, you will not be able to search for itself using find.

This also explains why wrapping a “container” element makes your code work.

EDIT A simple workaround would be, as the OP said, to warp the html into a container such as a div:

var content = $('<div/>').append(html);
content.find('#test'); // returns the right div
Sign up to request clarification or add additional context in comments.

4 Comments

+1 of course, however this will also work using the first HTML: alert($(html).find('#test').andSelf().html()); :)
Upon further inspection, this does not work. Try your same alert but instead of passing #test, pass #wrongid. You'll see it still (incorrectly) alerts the html from #test.
Indeed, this code doest not do what I was expecting. My explanation remains right but your workaround is imho the simplest working trick. I'm editing the answer.
Yes, I would not have come up with my solution without your and Effata's answers.
2

It seems the jQuery parser strips away everything but the body. If you do a console.log you get these results:

html = '<html><body><div id="test">This is just a test</div></body></html>';
console.log( $(html) );
= [<div id=​"test">​This is just a test​</div>​]

Which means you run find on the #test div itself, hence you won't get a result.

Comments

0

Thank you @Effata and @Zopieux for helping me figure this out. @Effata, unfortunately your trick doesn't seem to work. If you pass it an incorrect selector (such as #wrongid), it still seems to return the contents of #test.

Here is the solution I found that seems to work for all situations. Basically all I'm doing is wrapping the HTML in a <div> before executing the .find() method.

html = '<html><body><div id="test">This is just a test</div></body></html>';
alert( $("<div />").append(html).find("#test").html() );

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.