5

请看下面的代码:

http://jsfiddle.net/htdTg/2/

在第一个链接中有一个包含 html 特殊字符的标题属性,&lt;后跟“!” (实际上跟在哪个字符后面并不重要)。当我们使用 jQuery 的 attr() 函数获取该标题属性的值时,html 被破坏(您可以看到,只要以下文本也丢失,就没有打印“<”字符。

在第二个链接中,唯一的区别是我在之后添加了一个空格&lt;,现在它可以按预期工作。

您认为这是 jQuery 中的错误还是我只是不明白?

PS。如果您认为我在做一些奇怪的事情 - 这只是一些工具提示插件中的一段代码。

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: &lt;! Now you know it?</div>");​
4

6 回答 6

5

这很有趣。title我查找了属性中可以包含哪些文本,并且参考中说:

用户代理应该如下解释属性值:

  1. 用字符替换字符实体,
  2. 忽略换行,
  3. 用一个空格替换每个回车符或制表符。

显然,这是预期的行为。&lt;正在被<浏览器解析,可能会被 jQuery 解释为 HTML。

您也应该逃避&符号:

&amp;lt;

演示:http: //jsfiddle.net/htdTg/9/

更好的演示:http: //jsfiddle.net/PsZeY/6/

于 2012-12-12T20:05:40.327 回答
3

为什么会发生?

发生这种情况是因为&lt;! Now you know it? </div>转换为<! Now you know it? </div-->

根据 HTML 标准 <!>注释结构的开始和结束。请注意,这是评论结构而不是评论。因此 browwer 将其余部分转换为注释,除非它得到一个 end delimiter >

来自W3C

<!-- this is a comment -->
<!-- and so is this one,
    which occupies more than one line -->

标记声明打开分隔符 ( <!) 和注释打开分隔符 ( )之间不允许有空格--,但注释关闭分隔符 ( --) 和标记声明关闭分隔符 (">") 之间允许使用空格。一个常见的错误是在评论中包含一串连字符 ( ---)。作者应避免在评论中放置两个或更多相邻的连字符。

也在这里

SGML 中注释声明的语法是

 comment declaration =
    MDO ("<!"), (comment, ( s | comment )* )?, MDC (">")
 comment =
    COM ("--"), SGML character*, COM ("--")

如何解决?

你已经知道了。用来&amp;代替&。所以写&amp;lt;!而不是&lt;!. 这将使&lt;附加到正文元素而不是<!注释结构打开。

于 2012-12-12T19:59:58.907 回答
1

在这种情况下...

title="<div style='color:red'>This is the less than sign: &lt;! Now you know it?</div>"

&lt;!被转换为<!HTML 注释的开头,以及它不在浏览器窗口中呈现的确切原因。

在所有情况下,您都不应该在属性中包含 HTML 实体。改用这个...

title="&lt;div style='color:red'&gt;This is the less than sign: &amp;lt;! Now you know it?&lt;/div&gt;"

​http://jsfiddle.net/htdTg/5/

如果要保留 HTML 实体,请使用&lt;div&gt;to处理<div>. 或者,&amp;lt;div&amp;gt;将实际呈现 <div>在浏览器窗口中。

见:http: //jsfiddle.net/htdTg/8/

因此,如果您希望浏览器实际显示 a <!,请使用以下命令:&amp;lt!

于 2012-12-12T20:04:48.867 回答
1

我不确定您是在问问题还是实际上在寻找问题的解决方案。如果是后者,那么奇怪的是这似乎工作正常:&amp;lt;

更新代码:

HTML:

<a href="#" title="<div style='color:red'>This is the less than sign: &amp;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: &amp;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: &lt;! Now you know it?</div>");​

更新小提琴:http: //jsfiddle.net/htdTg/3/

于 2012-12-12T19:56:24.487 回答
1

文本没有遗漏问题是它被评论&lt;!了,因为它<!被翻译成<!--(不知道为什么),它在html.

如果您检查您的 html,您将看到以下内容。

<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> 

于 2012-12-12T19:57:28.287 回答
1

真的没有错。。

问题是必须对属性内部的 html 进行编码。您已经对<as进行了编码&lt;,这意味着它将被读取为<

所以.attr() 将返回一个纯<字符而不是编码的..

它不显示的原因是.append如果它认为其中有 html,它将尝试解析 html。它找到<!文本并将其视为 html 注释。 实际上这是由浏览器直接完成的


如果你看

var e = document.createElement('div');
e.innerHTML = '<!';
console.log(e.innerHTML);

设置为 div 后,您会看到 div 的内部 HTML<!<!---->.

所以这就是浏览器解释这段代码的方式..它与jQuery无关..

于 2012-12-12T20:08:04.743 回答