Wszystkie opublikowane do tej pory odpowiedzi zawierają właściwe rozwiązania, jednak żadna z nich nie była w stanie poprawnie wyjaśnić przyczyny leżącej u podstaw konkretnego problemu.
Facelets to technologia widoku oparta na języku XML, która wykorzystuje XHTML + XML do generowania danych wyjściowych HTML. XML ma pięć znaków specjalnych, które są specjalnie traktowane przez parser XML:
<
początek tagu.
>
koniec tagu.
"
początek i koniec wartości atrybutu.
'
alternatywny początek i koniec wartości atrybutu.
&
początek podmiotu (który kończy się ;
).
W przypadku &
których nie następuje #
(np  
,  
itp), parser XML jest niejawnie szuka jednej z pięciu predefiniowanych nazw jednostki lt
, gt
, amp
, quot
i apos
, lub dowolny ręcznie zdefiniowana nazwa podmiotu . Jednak w twoim konkretnym przypadku byłeś używany &
jako operator JavaScript, a nie jako jednostka XML. To całkowicie wyjaśnia błąd analizy XML, który otrzymałeś:
Nazwa jednostki musi znajdować się bezpośrednio po znaku „&” w odniesieniu do jednostki
Zasadniczo piszesz kod JavaScript w niewłaściwym miejscu, w dokumencie XML zamiast w pliku JS, więc powinieneś odpowiednio uciekać przed wszystkimi znakami specjalnymi XML. &
Musi być uciekł jak &
.
Tak więc w twoim konkretnym przypadku
if (Modernizr.canvas && Modernizr.localstorage &&
musi stać się
if (Modernizr.canvas && Modernizr.localstorage &&
aby był zgodny z XML.
Jednak to sprawia, że kod JavaScript jest trudniejszy do odczytania i utrzymania. Jak stwierdzono w doskonałym dokumencie Mozilla Developer Network Writing JavaScript for XHTML , kod JavaScript należy umieścić w bloku danych znakowych (CDATA). Zatem w kategoriach JSF byłoby to:
<h:outputScript>
<![CDATA[
// ...
]]>
</h:outputScript>
Parser XML zinterpretuje zawartość bloku jako dane znakowe „zwykłe”, a nie jako XML, a zatem interpretuje znaki specjalne XML „tak jak jest”.
Ale znacznie lepiej jest po prostu umieścić kod JS we własnym pliku JS, który dołączasz za pomocą <script src>
lub w terminologii JSF, pliku <h:outputScript>
.
<h:outputScript name="onload.js" target="body" />
(zwróć uwagę na target="body"
; w ten sposób JSF automatycznie wyrenderuje plik <script>
na samym końcu <body>
, niezależnie od tego, gdzie <h:outputScript>
się znajduje, uzyskując tym samym efekt, co z window.onload
i $(document).ready()
; więc nie musisz już ich używać w tym skrypcie)
W ten sposób nie musisz martwić się o znaki specjalne XML w swoim kodzie JS. Jako dodatkowy bonus, daje to możliwość, aby przeglądarka buforowała plik JS, tak aby całkowity rozmiar odpowiedzi był mniejszy.
Zobacz też:
application/xhtml+xml
zamiasttext/html
, co z kolei spowodowałoby kilka błędów w niektórych przeglądarkach, głównie MSIE. Zobacz także dokument „Writing JavaScript for XHTML”. W JSF nie musisz tego robić, jeśli używasz<f:view contentType="text/html">
zamiast pozwalać automatycznemu odgadywaniu JSF / webbrowser działać. Zobacz też: stackoverflow.com/tags/xhtml/info&&
w instrukcji if jeden wiersz powyżej mojego błędu), ale także w wierszu komentarza; mój błąd był włączony// TODO KevinC & Victor: some todo
(teraz został zmieniony naand
…). Wielkie dzięki za ten post. Natknąłem się na to wcześniej jako poprawkę dla tego samego problemu co OP.Musisz dodać znacznik CDATA wewnątrz tagu script, chyba że chcesz ręcznie przejść przez wszystkie znaki XHTML i uciec od nich (np.
&
Musiałby stać się&
). Na przykład:<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>
źródło
Parser oczekuje zawartości HTML, więc postrzega go
&
jako początek jednostki, na przykładè
.Skorzystaj z tego obejścia:
<script type="text/javascript"> // <![CDATA[ Javascript code here // ]]> </script>
więc określasz, że kod nie jest tekstem HTML, ale tylko danymi, które mają być używane tak, jak są.
źródło
Zrobić
<script>//<![CDATA[ /* script */ //]]></script>
źródło
Jeśli z jakiegoś powodu używasz XHTML, zwróć uwagę, że XHTML 1.0 C 4 mówi: „Użyj zewnętrznych skryptów, jeśli twój skrypt używa <lub & lub]]> lub -.” Oznacza to, że nie należy osadzać kodu skryptu wewnątrz
script
elementu, ale umieścić go w osobnym pliku JavaScript i odnosić się do niego za pomocą<script src="foo.js"></script>
.źródło
Na wypadek, gdyby pojawił się ktoś z Bloggera, miałem ten problem podczas używania
Beautify
rozszerzenia w VSCode. Nie używaj tego, nie używajbeautify
.źródło