in JavaScript einen String mit Zeilenumbruch notieren
snorri
- javascript
Hi alle,
ich habe gerade einen Fall, da muss ich längere HTML-Schnipsel durch eine JavaScript-Funktion ausgeben lassen, d.h. das HTML steht in einem JavaScript-String. Das ist ein bissel lästig, denn ich darf da ja keine Zeilenumbrüche in den Quellcode bauen. Es geht also nicht so:
var bla = "
<div>
<ul>
<li>eins</li>
<li>zwei</li>
<ul>
<div>
"
... sondern nur so:
var bla = "<div><ul><li>eins</li><li>zwei</li><ul><div>"
... was umso unlesbarer wird, je länger die HTML-Schnipsel werden.
Gibt's da einen Trick?
-- snorri
Ja. Backslash-n ("\n").
Gruß, LX
Du meinst so?
var bla = "<div>\n<ul>\n<li>eins</li>\n<li>zwei</li>\n<ul>\n<div>"
Das macht den JavaScript-Quellcode aber nicht gerade lesbarer :-)
Ich sehe schon, ich habe mich nicht ganz klar ausgedrückt: Mir geht es nicht um die Lesbarkeit des HTML-Codes, sondern des JavaScripts, das das HTML ausgibt.
-- snorri
"<div>"+
"<div>"...
Oder
"<div>\
<div>"...
Gruß, LX
var bla = "<div>\n<ul>\n<li>eins</li>\n<li>zwei</li>\n<ul>\n<div>"
Das macht den JavaScript-Quellcode aber nicht gerade lesbarer :-)
ich empfehle sogar
var bla = "<div><ul><li>eins</li><li>zwei</li><ul><div>"
zur Erhöhung der Lesbarkeit von JavaScript gibts die Kommentarmöglichkeit, da musst du nicht das Script unnötig verkomplizieren.
Hi,
falls es dir um die Lesbarkeit im JS-Code geht:
var bla =
"<div>"
+" <ul>"
+" <li>eins</li>"
+" <li>zwei</li>"
+" <ul>"
+"<div>";
~dave
Hi dave,
OK, das ist besser als alles in einen Bandwurm, aber doch ein wenig unpraktisch ...
-- snorri
[latex]Mae govannen![/latex]
Es geht also nicht so:
var bla = "
<div>
<ul>
<li>eins</li>
<li>zwei</li>
<ul>
<div>
"
Aber so:
~~~javascript
var bla = "\
<div>\
<ul>\
<li>eins</li>\
<li>zwei</li>\
<ul>\
<div>\
"
Wobei das auch nicht schön ist.
Stur lächeln und winken, Männer!
Kai
Hi Kai,
das ist jedenfalls die brauchbarste Option, die ich bisher gesehen habe. Der Aufwand beim Coden ist überschaubar und es funktioniert in allen Browsern.
Danke!
-- snorri
Hi!
das ist jedenfalls die brauchbarste Option, die ich bisher gesehen habe. Der Aufwand beim Coden ist überschaubar und es funktioniert in allen Browsern.
Vermutlich macht sie das, aber sie ist in der ECMAScript-Spezifikation als unzulässig beschrieben. http://www.ecma-international.org/publications/standards/Ecma-262.htm - Seite 13 kurz vor Kapitel 7.
Lo!
@@dedlfix:
nuqneH
Vermutlich macht sie das, aber sie ist in der ECMAScript-Spezifikation als unzulässig beschrieben. http://www.ecma-international.org/publications/standards/Ecma-262.htm - Seite 13 kurz vor Kapitel 7.
?? Was genau meinst du da?
Ich denke, du meinst entweder eine andere Stelle oder du interpretierst diese Stelle falsch.
Qapla'
Hi!
Vermutlich macht sie das, aber sie ist in der ECMAScript-Spezifikation als unzulässig beschrieben. http://www.ecma-international.org/publications/standards/Ecma-262.htm - Seite 13 kurz vor Kapitel 7.
?? Was genau meinst du da?
"... if the Unicode escape sequence \u000A occurs within a string literal in a Java program, it is likewise interpreted as a line terminator, which is not allowed within a string literal—one must write \n instead of \u000A to cause a line feed to be part of the string value of a string literal."
Aber das ist wohl doch nicht das, was ich wollte, weil es sich auf Java bezieht.
Als ich den Kontextwechsel-Artikel schrieb, machte mich molily auf das Thema aufmerksam. Leider hatte ich damals keine Quellenangabe hinzugefügt sondern nur meine Interpretation in den Artikel geschrieben.
Ich denke, du meinst entweder eine andere Stelle oder du interpretierst diese Stelle falsch.
Es kommt noch eine Stelle bei den String-Literalen im Kapitel 7.8.4 auf Seite 24 (34. Seite des PDF-Dokuments).
"NOTE A line terminator character cannot appear in a string literal, except as part of a LineContinuation to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A."
Auseinandergenommen:
A line terminator character cannot appear in a string literal,
das Problem des OPs
except as part of a LineContinuation to produce the empty character sequence.
LineContinuation ist definiert als Backslash plus (CR)LF (und noch ein paar mehr Möglichkeiten) und erzeugt nur einen Leerstring.
The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A.
Nur \n und \u000A können zum Einfügen eines Zeilenumbruchs verwendet werden.
Also update ich mein Wissen nun, dass zwar \ vor einem Zeilenumbruch erlaubt ist, aber nur einen Zeilenumbruch im Code erzeugt, nicht jedoch im String selbst.
Danke fürs Intervenieren.
Lo!
Hallo,
das ist jedenfalls die brauchbarste Option, die ich bisher gesehen habe. Der Aufwand beim Coden ist überschaubar und es funktioniert in allen Browsern.
Dabei muss man aber gut aufpassen, z.B. funktioniert folgendes wie gewünscht:
var html = "\
[code lang=html]<ul>\
<li>1</li>\
<li>1</li>\
</ul>\
"
[/code]
Folgendes funktioniert dagegen nicht:
var html = "\
[code lang=html]<ul>\
<li>1</li>\
<li>1</li>\
</ul>\
"[/code]
Alles klar?
Don P
[latex]Mae govannen![/latex]
Dabei muss man aber gut aufpassen, z.B. funktioniert folgendes wie gewünscht:
var html = "\
[code lang=html]<ul>\ <li>1</li>\ <li>1</li>\ </ul>\
> "
> [/code]
> Folgendes funktioniert dagegen nicht:
> ~~~javascript
> var html = "\
> [code lang=html]<ul>\
> <li>1</li>\
> <li>1</li>\
> </ul>\
"[/code]
Alles klar?
Mir nicht. Ich sehe da keinen Unterschied.
Benenne ich den zweiten Versuch um und teste mit alert(html === html2) kommt true heraus. Also exakt gleich.
Stur lächeln und winken, Männer!
Kai
Hallo,
Mir nicht. Ich sehe da keinen Unterschied.
Ja, anscheinend ist mir der "Trick verreckt".
Hatte ein Leerzeichen hinter einen der Backslashs geschmuggelt, aber beim Posten ist es wohl verloren gegangen.
Dem Backslash darf jedenfalls nichts mehr folgen außer dem Zeilenende. Sollte man da aus Versehen noch irgendwelchen Whitespace stehen haben, dann ist der Fehler schwer zu sehen.
Gruß, Don P
[latex]Mae govannen![/latex]
Mir nicht. Ich sehe da keinen Unterschied.
Ja, anscheinend ist mir der "Trick verreckt".
Hatte ein Leerzeichen hinter einen der Backslashs geschmuggelt, aber beim Posten ist es wohl verloren gegangen.Dem Backslash darf jedenfalls nichts mehr folgen außer dem Zeilenende. Sollte man da aus Versehen noch irgendwelchen Whitespace stehen haben, dann ist der Fehler schwer zu sehen.
Das stimmt allerdings. Fieser Fallstrick.
Aber wer benutzt schon Editoren, die „trailing whitespace“ nicht abschneiden? SCNR
Ich persönlich benutze ohnehin nie Zeichenketten, die über mehrere Zeilen gehen, daher wäre mir das schon aus diesen beiden Gründen nicht aufgefallen.
Stur lächeln und winken, Männer!
Kai
@@Kai345:
nuqneH
Ich persönlich benutze ohnehin nie Zeichenketten, die über mehrere Zeilen gehen
Ich schon gelegentlich.
Qapla'
Das hier geht leider nur im Firefox, alle anderen ignorieren das:
var bla = (<r><![CDATA[
<div>
<ul>
<li>eins</li>
<li>zwei</li>
<ul>
<div>
]]></r>).toString();
Schade, das wäre recht praktikabel.
-- snorri
Hi,
ich habe gerade einen Fall, da muss ich längere HTML-Schnipsel durch eine JavaScript-Funktion ausgeben lassen, d.h. das HTML steht in einem JavaScript-String. Das ist ein bissel lästig, denn ich darf da ja keine Zeilenumbrüche in den Quellcode bauen.
wie wäre es, wenn du darauf verzichtest?
Stattdessen könntest du die HTML-Schnippsel bereits im Markup der Seite reinbauen (mit CSS ausblenden), allerdings nur als "Skelett", d.h. ohne anzuzeigende Daten.
Wenn JavaScript verfügbar ist, holst du dir den Schnippsel-Knoten und speicherst ihn irgendwo zwischen, gleichzeitig entfernst du ihn aus dem DOM.
Wenn du den Schnippsel brauchst, dann klonst du den Knoten (wenn er mehrmals vorhanden sein kann, ansonsten direkt verwenden) und fügst mit DOM-Methoden die dynamischen Werte ein und hängst den Knoten daraufhin wieder ins DOM.
Dies hat den Vorteil:
Der Roh-Schnippsel kann in HTML beschrieben werden, tiefergehende Javascript-Kenntnisse sind nicht notwendig, um das Markup zu ändern (Trennung der Applikationslogik in Javascript von Darstellung (HTML)). Weiterhin ist er, getreu deinen Anforderungen, "schön" formatierbar.
Nachteil: wenn kein Javascript verfügbar ist, hängt nutzloser Ballast im DOM rum.
Bis die Tage,
Matti
ich habe gerade einen Fall, da muss ich längere HTML-Schnipsel durch eine JavaScript-Funktion ausgeben lassen, d.h. das HTML steht in einem JavaScript-String. Das ist ein bissel lästig, denn ich darf da ja keine Zeilenumbrüche in den Quellcode bauen.
In größeren JavaScript-Anwendungen hat man das Problem ständig. Wir lösen das meist, indem wir die Templates erst einmal nicht ins JavaScript integrieren, sondern sie in separaten Dateien ablegen. Die werden dann entweder clientseitig als Strings eingelesen oder serverseitig automatisiert in JavaScript-Dateien umgewandelt.
Das Füllen erfolgt dann mit einer Template-Engine wie Mustache oder Eco. Da wir meist im Rails-Umfeld HTML-Templates in Haml und die JavaScripte in CoffeeScript schreiben, haben wir einen Haml-Coffee-Parser entwickelt. Die Templates werden damit zu JavaScripten (Funktionen) kompiliert.
Für kleinere Sachen würde ich die von Matti vorgeschlagene Lösung favorisieren. Übrigens lässt sich auch HTML-Code in script-Elementen unterbringen, ohne dass es sich um JavaScript handelt. Beispielsweise kann man ein Template so in den HTML-Code schreiben:
<script type="text/x-mustache" id="foo-view">
<h2>{{title}}</h2>
<p>{{text}}</p>
<p><img src="{{imageURL}}"></p>
</script>
Das ist eine Art CDATA-Abschnitt, nur ohne XML. Der MIME-Typ im type-Attribut muss nur irgendeiner sein, den der Browser nicht als JavaScript erkennt. script-Elemente kann man so natürlich nicht verschachteln.
Mit JavaScript holt man sich dann den Inhalt von foo-view, lässt z.B. Mustache darüber laufen und fügt die entstehenden DOM-Elemente irgendwo ein.
Der Vorteil zum Einbinden als HTML und Verstecken ist hier, dass das HTML nicht geparst wird, sondern als String vorliegt. Beim Parsen würde Quatsch passieren, z.B. würde er versuchen, die URL {{imageURL}} zu laden.
Wenn man mehr Logik braucht, als Mustache einem bietet, so gibt es wie gesagt komplexere Template-Lösungen, bei denen sich JavaScript oder CoffeeScript im Template verwenden lässt.
Mathias
Hi,
Das Füllen erfolgt dann mit einer Template-Engine wie Mustache oder Eco.
Danke für diese beiden Links. Nach ein wenig rumspielen mit Mustache bin ich später auf Closure Templates aus den Google Labs gestossen. Hat den leichten Vorteil, dass die Templates schon "kompiliert" vorliegen und nicht zur Laufzeit geparst werden muss.
Bis die Tage,
Matti