Reputation: 13509
Please take a look at the following code:
In the first link there is a title attribute containing the html special character <
followed by "!" (it doesn't matter which character it is followed by actually).
When we take the value of that title attribute with jQuery's attr() function the html is broken (you can see that there is no "<" character printed as long as the following text is also missing.
In the second link the only difference is that I have added a space after <
and now it works as expected.
Do you think it's a bug in jQuery or I just don't understand something?
PS. If you think I'm doing something strange - it's just some piece of code from some tooltip plugin.
HTML:
<a href="#" title="<div style='color:red'>This is the less than sign: <! Now you know it?</div>">This is a link</a><br>
<a href="#" title="<div style='color:red'>This is the less than sign: < ! Now you know it?</div>">This is a link</a><br>
jQuery:
$('a').each(function() {
$('body').append($(this).attr('title')); });
// just to exclude that it's append() function's fault :)
$('body').append("<div style='color:red'>This is the less than sign: <! Now you know it?</div>");
Upvotes: 5
Views: 3303
Reputation: 195982
Nothing is really wrong..
The issue is that html inside attributes must be encoded. You already have encoded the <
as <
and that means that it will be read as <
.
So .attr()
will return a pure <
character and not the encoded..
The reason it does not show is with actually this is done directly by the browser..append
which will try to parse the html if it thinks there is html in it.. It finds the <!
text and it considers it as html comment.
If you look at
var e = document.createElement('div');
e.innerHTML = '<!';
console.log(e.innerHTML);
you will see that the inner HTML of the div after setting it to <!
is <!---->
.
So that is how the browsers interpret this code.. it has nothing to do with jQuery..
Upvotes: 1
Reputation: 57650
This is happening because <! Now you know it? </div>
is converted to <! Now you know it? </div-->
According to HTML standard <!
and >
is the start and end of comment structure. Note this is comment structure not comment. Hence browwer converts the rest as comment unless it gets a end delimiter >
.
From W3C
<!-- this is a comment --> <!-- and so is this one, which occupies more than one line -->
White space is not permitted between the markup declaration open delimiter(
<!
) and the comment open delimiter (--
), but is permitted between the comment close delimiter (--
) and the markup declaration close delimiter (">"). A common error is to include a string of hyphens (---
) within a comment. Authors should avoid putting two or more adjacent hyphens inside comments.
Also in here
The syntax for comment declarations in SGML is
comment declaration = MDO ("<!"), (comment, ( s | comment )* )?, MDC (">") comment = COM ("--"), SGML character*, COM ("--")
You already know it. use &
to replace &
. So write &lt;!
instead of <!
. This will make <
appended to body element instead of <!
which is comment structure opening.
Upvotes: 3
Reputation: 6431
I'm not sure if you're just asking the question or actually looking for a solution to the problem. If the latter, then strangely this seems to work fine: &lt;
Updated code:
HTML:
<a href="#" title="<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>">This is a link</a><br>
<a href="#" title="<div style='color:red'>This is the less than sign: &lt; ! Now you know it?</div>">This is a link</a><br>
jQuery:
$('a').each(function() {
$('body').append($(this).attr('title')); });
// just to exclude that it's append() function's fault :)
$('body').append("<div style='color:red'>This is the less than sign: <! Now you know it?</div>");
Updated fiddle: http://jsfiddle.net/htdTg/3/
Upvotes: 1
Reputation: 26320
The text isn't missing the problem is that it get commented because <!
is the same of <!
which is being translated to <!--
(don't know why) which starts a comment in html
.
If you inspect your html you'll see the following.
<div style='color:red'>This is the less than sign: <!-- Now you know it? --></div>
<div style='color:red'>This is the less than sign: < ! Now you know it?</div>
Upvotes: 1
Reputation: 98728
In this case...
title="<div style='color:red'>This is the less than sign: <! Now you know it?</div>"
<!
is converted to <!
which is the start of a HTML comment and exactly why it does not render in the browser window.
For all cases, you should not have HTML entities contained within an attribute. Use this instead...
title="<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>"
http://jsfiddle.net/htdTg/5/
If you want to preserve the HTML entities, use <div>
to be processed as <div>
. Alternatively, &lt;div&gt;
will actually render <div>
in the browser window.
See: http://jsfiddle.net/htdTg/8/
So if you want the browser to actually display a <!
, then use this: &lt!
Upvotes: 1
Reputation: 298156
This is pretty interesting. I looked up what text can be in a title
attribute and the reference says:
User agents should interpret attribute values as follows:
- Replace character entities with characters,
- Ignore line feeds,
- Replace each carriage return or tab with a single space.
Apparently, this is the expected behavior. <
is being parsed as <
by the browser, which might be interpreted as HTML by jQuery.
You should be escape the ampersand as well:
&lt;
Demo: http://jsfiddle.net/htdTg/9/
Even better demo: http://jsfiddle.net/PsZeY/6/
Upvotes: 5