我想提出一个帕克曼游戏我* .xhtml页面上。(我使用JSF 2和primefaces 3.5)
然而,
当我“翻译”在XHTML的html页面,我得到这个脚本错误:
<script>
var el = document.getElementById("pacman");
if (Modernizr.canvas && Modernizr.localstorage &&
Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
} else {
el.innerHTML = "Sorry, needs a decent browser<br /><small>" +
"(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
}
</script>
在行:
if (Modernizr.canvas && Modernizr.localstorage &&
我得到:
实体名称必须紧跟在“&”在实体引用。
不知道如何解决这个问题?
所有答案公布至今都做出正确的解决方案,但是没有一个答案是能够正确解释具体问题的根本原因。
小面是使用XHTML + XML来产生HTML输出一个基于XML的视图技术。 XML具有具有XML解析器特殊处理五个特殊字符:
-
<
标签的开始。 -
>
标签的末端。 -
"
开始和属性值的结束。 -
'
的可供选择的起始和属性值的结束。 -
&
一个实体的开始(其与终止;
)。
在的情况下, &
未随后#
(例如 
 
等),XML解析器被隐含找五个一预定义的实体名称 lt
, gt
, amp
, quot
和apos
,或任何手动定义实体名称 。 然而,你的具体情况,您是使用&
作为一个JavaScript运营商,而不是一个XML实体。 这完全说明你得到了XML解析错误:
实体名称必须紧跟在“&”在实体引用
从本质上说,你写在错误的地方的JavaScript代码,XML文档,而不是一个JS文件,所以你应该相应地转义所有XML特殊字符。 在&
必须进行转义为&
。
因此,在您的特定情况下,
if (Modernizr.canvas && Modernizr.localstorage &&
必须成为
if (Modernizr.canvas && Modernizr.localstorage &&
使其XML-有效。
然而,这使得JavaScript代码难以阅读和维护。 作为Mozilla开发者网络的优秀的文件规定了XHTML编写JavaScript ,你应该把JavaScript代码中的字符数据(CDATA)块。 因此,在JSF而言,这将是:
<h:outputScript>
<![CDATA[
// ...
]]>
</h:outputScript>
XML解析器将解释块的内容为“普通的香草”字符数据而不是XML,因此解释XML特殊字符“原样”。
但是,更好的是只是把自己的JS文件中的JS代码,您包括由<script src>
或在JSF而言, <h:outputScript>
<h:outputScript name="onload.js" target="body" />
(注意target="body"
;这样JSF将自动呈现<script>
在的最末端<body>
无论在哪里<h:outputScript>
本身的位置,在此实现相同的效果,与window.onload
和$(document).ready()
所以你不需要在脚本中不再使用那些)
这样,您就不必担心您的JS代码XML的特殊字符。 作为一个额外的奖金,这让您有机会来让浏览器缓存中的JS文件,这样总有尺寸更小。
也可以看看:
- 错误解析/page.xhtml:错误示踪[行:42]实体“NBSP”被引用,但没有宣布
- 是否有可能使用JSF + Facelets的使用HTML 4/5?
- 如何引用CSS / JS /图像资源在Facelets的模板?
- 编写JavaScript的XHTML
您需要添加脚本标签内部的CDATA标签,除非你想手动经历和逃避所有XHTML字符(例如&
需要成为&
)。 例如:
<script>
//<![CDATA[
var el = document.getElementById("pacman");
if (Modernizr.canvas && Modernizr.localstorage &&
Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
} else {
el.innerHTML = "Sorry, needs a decent browser<br /><small>" +
"(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
}
//]]>
</script>
解析器期待一些HTML内容,因此它认为&
作为一个实体的开始,就像è
。
使用此解决办法:
<script type="text/javascript">
// <![CDATA[
Javascript code here
// ]]>
</script>
所以你指定的代码不是HTML文本,但使用只是数据是。
做
<script>//<![CDATA[
/* script */
//]]></script>
如果你使用XHTML,出于某种原因,注意, XHTML 1.0的C 4说:“使用外部脚本,如果你的脚本使用<或&或]]>或- ”这是一个内部的,没有嵌入脚本代码script
元素但把它放入一个单独的JavaScript文件并指将其与<script src="foo.js"></script>
。