Supposedly a jquery object can be initialized from string. This can often happen when processing ajax results, i.e. I'm trying to replicate http://api.jquery.com/jQuery.post/
However, I'm seeing 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 alert shows: content.text() = helloworld
The second alert shows: content.html() = hello
What's happening here?
Thanks everyone for the explanations. I ended up adding another layer of <div>
to have a single child of <body>
, as in
<html>
<body>
<div> <=== added
<div>hello</div>
<div>world</div>
</div>
</body>
</html>
When parsing HTML fragments containing a body
element, browsers in general (and jQuery does this as well) will disregard everything except what's inside the body
element. So what you have there ends up being equivalent to:
var content = $("<div>hello</div><div>world</div>");
alert("content.text() = " + content.text());
alert("content.html() = " + content.html());
You end up with a jQuery object with two elements in it: The div
elements.
In jQuery, normally accessor functions (html
, val
, css
, etc.) only use the first element in the set when you use them as getters, and that's what html
is doing above. text
is an unusual accessor function in jQuery: It gives you the combined text of all of the elements in the set, not just the first.
We can see this in the docs, but it's still surprising. From html
:
Get the HTML contents of the first element in the set of matched elements or set the HTML contents of every matched element.
From text
:
Get the combined text contents of each element in the set of matched elements, including their descendants, or set the text contents of the matched elements.
(My emphasis in both cases.)
Browsers remove those html
and body
elements. The content
collection has only 2 div
elements.
When passing in complex HTML, some browsers may not generate a DOM that exactly replicates the HTML source provided. As mentioned, jQuery uses the browser's
.innerHTML
property to parse the passed HTML and insert it into the current document. During this process, some browsers filter out certain elements such as<html>
,<title>
, or<head>
elements. As a result, the elements inserted may not be representative of the original string passed.
This is the string representation of your content
collection:
content.map(function() { return this.outerHTML || this.nodeValue; }).get().join('');
// -> <div>hello</div><div>world</div>
.text()
method returns textContent/nodeValue
of all the elements in the collection:
content.text(); // -> helloworld
.and .html()
method returns innerHTML
of the first element in the collection:
content.html(); // -> hello
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With