mrjerk: string vs. richtext

Beitrag lesen

Hallo,

seit ich vor einigen Jahren begonnen habe mich mit JavaScript zu beschäftigen und feststellte, dass diese Sprache gar nicht so böse ich wie ich zuvor glaubte

Nein, ist sie in der Tat nicht :)

Warum zum Henker kann man Zeichenketten formatieren (und ähnliches)?

Tatsächlich habe ich mich das auch schon gefragt - so wahnsinnig sinnvoll ist es irgendwie nicht. Zumal die Formatiermöglichkeiten sich auf Tags beschränken, von denen inzwischen eh viele deprecated sind (blink u.ä.)

JavaScript scheint diese Dinge zu mischen also beide Datentypen (Klassen) in einer zu vereinen. Gibt mir aber gleichzeitig keine Methode an die Hand (soweit ich das bisher sehe) nur auf die Zeichenkette zuzugreifen ohne deren Formatierungen ("strip").

Eigentlich ist es so:
Die Formatierungsmethoden erzeugen widerrum einen String - der aus dem ursprünglichen String besteht plus den umgebenden HTML-Tags.

"Hallo".sup() entspricht "<sup>Hallo</sup>"

Dies ist nun in sich wieder halbwegs logisch. Ein String wird formatiert, in dem ein neuer String ezeugt wird, der zusätzlich Formatierungsangaben enthält.
Eine dazu inverse Funktion dazu gibt es tatsächlich nicht, könnte man sich aber schreiben, wenn man das wollte:

  
String.prototype.unsup = function () {  
   this = this.replace(/^<sup>/i, "");  
   this = this.replace(/<\/sup>$/i, "");  
}  

oder so ähnlich (ohne Gewähr ;) )

Woher weiß ich ob ich formatierten Text oder eine reine Zeichenkette erhalte, wenn ich z.B. einen Textknoten bzw. dessen Inhalt ergreife.

Du erhältst IMMER eine Zeichenkette...allerdings eine, die selbst noch weitere HTML-Tags enthalten kann.

Noch ein kleines Beispiel:

  
<?xml  
<!-- xml-Deklaration, namensraum, PiPaPo... -->  
<rootelement> <!-- Sagen wir es wäre ein Integer-Element. -->  
JavaScript-String-Objekt mit Formatierung, welches aber ein Integer darstellt. Sagen wir "5".italics(); oder so.  
</rootelement>  
?>  

> Was ist das?  
  
Schön, nehmen wir an, Du hast das Ding als XML-Dokument in einer Variable gespeichert (z.b. als Antwort auf einen AJAX-Request o.ä.), nennen wir sie einfach mal xml.  
  
[code lang=javascript]  
alert (xml.getElementsByTagName("rootelement")[0].firstChild.data);  
// Liefert ""5".italics();"  

Dieses Beispiel holt sich den Tag "rootelement", davon den allerersten mit [0] (es könnte ja mehrere geben), davon den ersten Kindknoten (einen Textknoten der Dein "5.italics();" enthält) und gibt dessen Zeichendaten aus (also "5.italics();")
Diese Zeichendaten sind in diesem Zustand ein String - JavaScript weiß erstmal nicht, dass das was es da bekommt irgendwas mit JavaScript zu tun hat - es könnte auch "foobar" darin stehen, völlig egal.

Natürlich kannst Du jetzt JavaScript dazu zwingen, es gefälligst als JavaScript-Code zu behandeln:

  
alert (eval(xml.getElementsByTagName("rootelement")[0].firstChild.data));  
// Liefert "<i>5</i>"  

Was passiert? JavaScript wird mit "eval" angewiesen, die Zeichendaten als JavaScript zu interpretieren.
JavaScript erzeugt also erstmal ein neues String Objekt ("5").
(Dass "5" auch ein Integer sein könnte, interessiert JavaScript in diesem Moment herzlich wenig).

An dem erstellten String Objekt ("5") wird jetzt die Methode "italics()" aufgerufen, also bastelt JS ein "<i>" und "</i>" drumherum.
Das Resultat ist und bleibt aber ein String - dass man das ganze auch als HTML-Knoten sehen könnte, ist für JS abermals nicht von Belang.

Erst wenn Du dieses Konstrukt irgendwo in einen DOM-Baum einhängst, und dann als DOM-Objekt einliest, hat JS ein Verständnis davon, dass es mit HTML-Knoten zu tun bekommt.

  
// html ist ein String, nämlich "<i>5</i>"!  
var html = (eval(xml.getElementsByTagName("rootelement")[0].firstChild.data));  
  
// Einhängen ins DOM  
document.getElementById("someHTMLNode").innerHTML = html;  
  
// Jetzt kann man "vernünftig" darauf arbeiten  
var italicsNode = document.getElementById("someHTMLNode").firstChild;  
  
// Gibt "i" zurück, welche Überraschung :)  
alert (italicsNode.nodeName);  
  
// Gibt "5" zurück  
alert (italicsNode.firstChild.data);  

*Hinweis: Alle Codebeispiele habe ich nicht ausprobiert, weiß also nicht ob sie 1:1 so funktionieren, dienen nur dem Verständnis ;)

Ich hoffe, das hilft etwas weiter?

Viele Grüße,
Jörg