Ответ 1
Все ответы, опубликованные до сих пор, дают правильные решения, однако ни один ответ не смог правильно объяснить основную причину конкретной проблемы.
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 будет интерпретировать содержимое блока как символьные данные "plain vanilla", а не как 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()
, поэтому вам больше не нужно использовать их в script)
Таким образом, вам не нужно беспокоиться о специальных символах XML в вашем JS-коде. В качестве дополнительного бонуса это дает вам возможность позволить браузеру кешировать JS файл, чтобы уменьшить общий размер ответа.