Имя объекта должно сразу следовать за "&" в ссылке на объект
Я хочу разместить упаковочную игру на своей странице *.xhtml (я использую jsf 2 и primefaces 3.5).
Тем не мение,
когда я "перевел" HTML-страницу в xhtml, я получаю сообщение об ошибке в этом сценарии:
<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 &&
я получил:
Имя объекта должно следовать сразу за "&" в ссылке на объект.
Есть идеи, как это исправить?
5 ответов
Все ответы, опубликованные до сих пор, дают правильные решения, однако ни один из них не смог правильно объяснить основную причину конкретной проблемы.
Facelets - это технология представления на основе XML, которая использует XHTML+XML для генерации вывода HTML. 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 Developer Network, пишущем JavaScript для XHTML, вы должны поместить код 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()
; так что вам больше не нужно использовать их в этом скрипте)
Таким образом, вам не нужно беспокоиться о специальных символах XML в вашем коде JS. В качестве дополнительного бонуса это дает вам возможность разрешить браузеру кэшировать файл JS, чтобы общий размер ответа был меньше.
Смотрите также:
Вам нужно добавить тег CDATA внутри тега script, если вы не хотите вручную проходить и экранировать все символы 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, а просто данные, которые будут использоваться как есть.
Если по какой-то причине вы используете XHTML, обратите внимание, что в XHTML 1.0 C 4 написано: "Используйте внешние сценарии, если ваш сценарий использует <или & или]]> или -". То есть не вставляйте код сценария в script
элемент, но поместите его в отдельный файл JavaScript и обратитесь к нему с помощью <script src="foo.js"></script>
,
На случай, если приедет кто-то из Blogger, у меня возникла эта проблема при использовании
Beautify
расширение в VSCode. Не используйте это, не
beautify
Это.