Jquery.html () only returns first text when loaded from string
Presumably the jquery object can be initialized from a string. This often happens when processing ajax results, i.e. I am trying to replicate http://api.jquery.com/jQuery.post/
However, I see strange behavior:
function test() {
var content = $("<html><body><div>hello</div><div>world</div></body></html>");
alert("content.text() = " + content.text());
alert("content.html() = " + content.html());
}
The first warning shows: content.text () = helloworld
The second warning shows: content.html () = hello
What's going on here?
Decision
Thanks everyone for the explanations. I ended up adding another layer <div>
to have one child <body>
as in
<html>
<body>
<div> <=== added
<div>hello</div>
<div>world</div>
</div>
</body>
</html>
source to share
When parsing HTML snippets that contain an element body
, browsers in general (and jQuery does that as well) will ignore everything except what's inside the element body
. So what you have there ends up with an equivalent:
var content = $("<div>hello</div><div>world</div>");
alert("content.text() = " + content.text());
alert("content.html() = " + content.html());
As a result, you get a jQuery object with two elements in it: div
.
In jQuery usually access function ( html
, val
, css
etc.) only element used first in the set, when you use them as getters, and that's what html
makes the above. text
is a fancy access feature in jQuery: it gives you the combined text of all the elements in the set, not just the first.
We see this in the docs, but it's still amazing. From html
:
Get the HTML content of the first element in a set of matched elements, or set the HTML content of each matched element.
From text
:
Get the combined text content of each element in a set of matched elements, including their descendants, or set the text content of matched elements.
(My emphasis is on both.)
source to share
Browsers remove those elements html
and body
. The collection content
only has 2 items div
.
When rendering complex HTML, some browsers may not generate a DOM that accurately replicates the provided HTML source. As mentioned, jQuery uses the browser property
.innerHTML
to parse past HTML and insert it into the current document. During this process, some browsers filter out certain elements such as elements<html>
,<title>
or<head>
. As a result, the inserted elements may not match the original passed string.
This is a string representation of your collection content
:
content.map(function() { return this.outerHTML || this.nodeValue; }).get().join('');
// -> <div>hello</div><div>world</div>
.text()
returns textContent/nodeValue
all elements of the collection:
content.text(); // -> helloworld
.and .html()
returns the innerHTML
first item in the collection:
content.html(); // -> hello
source to share
This is how yours looks content
in the browser:
"content = " Object { 0: <div>, 1: <div>, length: 2 }
Basically it is some kind of a set of two elements.
And here's what http://api.jquery.com/html/ say:
Get the HTML content of the first element in a set of matched elements
source to share