我想在我的*.xhtml页面上放一个包工头游戏(我使用的是jsf 2和primefaces 3.5)
但是,我想在我的*.xhtml页面上放一个包装人游戏。
当我在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 &&
我得到了。
实体名称必须紧跟在实体引用中的'&'后面。
任何想法如何解决这个问题?
到目前为止,所有的答案都给出了正确的解决方案,但是没有一个答案能够正确解释具体问题的根本原因。
Facelets是一种基于XML的视图技术,使用XHTML+XML生成HTML输出。XML有五个特殊的字符,XML解析器对它们有特殊的处理。
<
标签的开始>
一个标签的结尾。"
一个属性值的开始和结束。'
一个属性值的开始和结束。&
一个实体的开始(以 ;
).如果是 &
后面没有 #
(例如  
,  
等),XML解析器隐含地在寻找五个 预定义实体名称 lt
, gt
, amp
, quot
和 apos
或任何 手动定义的实体名称. 然而,在你的特殊情况下,你使用的是 &
作为一个JavaScript操作符,而不是作为一个XML实体。这完全解释了你所得到的XML解析错误。
实体名称必须紧跟在实体引用中的"& "后面。
实质上,你写JavaScript代码的地方不对,是一个XML文档而不是JS文件,所以你应该对所有XML特殊字符进行相应的转义。在这里,我想说的是,你应该把所有的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文件,从而使总的响应大小更小。
你需要在脚本标签内添加一个CDATA标签,除非你想手动通过并转义所有的XHTML字符(例如,你需要在脚本标签内添加一个CDATA标签。&
将需要变成 &
). 比如说。
<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>
.