Deus Figendi: string vs. richtext

Guten Morgen,
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 brennt mir diese Frage unter den Nägeln:
Warum zum Henker kann man Zeichenketten formatieren (und ähnliches)?
Ich beziehe mich auf das http://de.selfhtml.org/javascript/objekte/string.htm@title=String-Objekt, welches allerlei Methoden mit sich bringt, die sich auf RichText beziehen.
Was ich meine ist: Ich kenne aus anderen Sprachen, dass es den Datentyp "Richtext" gibt (den ich nicht gerne verwende, weil die Handhabung oft recht kompliziert und verwirrend ist). Und es gibt natürlich String/Zeichenkette.
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").

Um es an einem Beispiel festzumachen: toLowerCase() ist eine typische Funktion (oder hier: Methode), die man auf Zeichenketten anwendet.
sub() hingegen ist es idR nicht (Ausnahmen mögen Zeichen sein, die es im Unicode nochmal extra als tiefergestellt gibt).

Mein Problem bei der Sache ist halt, dass ich das gedanklich nicht auseinander bekomme. Woher weiß ich ob ich formatierten Text oder eine reine Zeichenkette erhalte, wenn ich z.B. einen Textknoten bzw. dessen Inhalt ergreife.

Und wie gesagt, warum bietet mir "String" eine Methode namens "blink" anstatt dessen Elternelement.

Und was bedeutet das alles außerhalb des HTML/XML etc. -Kontext? Ich habe z.B. auch eine JS-Engine für mein Chatprogramm und das arbeitet nicht mit XML. (Formatierungen werden IRC-typisch mit Steuerzeichen geregelt).

Kann mir irgendjemand helfen dieses Problem zu lösen, also das Ganze einfach gedanklich in Ordnung zu bringen? Gibt es eine Denk-Krücke, die mir das Verständnis dafür erleichtert?

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?  
  
Ich hoffe ihr konntet meinen Gedankengängen folgen und ich hoffe weiterhin dass ihr Licht in meine geistige Plattenbausiedlung bringen könnt :)  

--
sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ_de:] zu:) fl:( ss:| ls:[ js:(
  1. @@Deus Figendi:

    nuqneH

    Ich beziehe mich auf das http://de.selfhtml.org/javascript/objekte/string.htm@title=String-Objekt, welches allerlei Methoden mit sich bringt, die sich auf RichText beziehen.

    Ich kann mir nur vorstellen, dass der Krempel aus Prä-CSS-Zeiten stemmt, als die Browserentwickler dachten, Webseitenentwicklern sowas in JavaScript zur Verfügung stellen zu müssen.

    Verwenden sollte man diese Methoden nicht, sondern sämtliche Style-Angaben per CSS tätigen.

    (Für small() hab ich allerdings doch einen Anwendungsfall gefunden.)

    Ob toLowerCase()/toUpperCase() verwendet werden sollten oder CSS 'text-transform', hängt davon ab, ob man die Daten verändern möchte oder lediglich in Klein- bzw. Großschreibung darstellen möchte.

    Qapla'

    --
    Volumen einer Pizza mit Radius z und Dicke a: pi z z a
  2. 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

    1. Vielen Dank für deine erleuchtende Antwort.

      Tatsächlich habe ich mich das auch schon gefragt

      Das freut mich, dass ich nicht der einzige bin den das irritiert :)

      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.

      Damit ist im Grunde alles klar und mein Weltbild auch wieder gerade. Es ist also gar kein formatierter String sondern nur ein string einschließlich Tags. Ob und welche Bedeutung diese Tags haben kommt dann ja wiederum auf das interprettierenden Gerät/Programm an.

      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();"

      Okay, da hast du mich falsch verstanden, ich meinte halt dass man das TextNode (daher String-Objekt, nicht einfach nur "string") mit dem Inhalt "5".italics(); in das DOM einhängt.  
      Jetzt weiß ich dass dann dort <i>5</i> reingeschrieben würde und das wiederum sollte das Schema oder DTD ablehnen (kommt wiederum auf den Parser an).  
      
      >   
      > Dieses Beispiel holt sich den Tag "rootelement", davon den allerersten mit [0] (es könnte ja mehrere geben)  
      
      nö kann's nicht, aber ich würde es ebenso greifen  
        
      Naja wie auch immer, du hast mich erleuchtet und wie gesagt kann ich mir jetzt auch was drunter vorstellen. Es ist also nicht //Text// sondern "<i>Text</i>" was das Element dann bedeutet hängt ja bekanntermaßen vom DOCTYPE ab.
      
      -- 
      sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ\_de:] zu:) fl:( ss:| ls:[ js:(
      
  3. Moin!

    Warum zum Henker kann man Zeichenketten formatieren (und ähnliches)?
    Ich beziehe mich auf das http://de.selfhtml.org/javascript/objekte/string.htm@title=String-Objekt, welches allerlei Methoden mit sich bringt, die sich auf RichText beziehen.

    Nein, tun sie nicht.

    Das, was das String-Objekt da kann, ist eine ziemlich simple und in der Praxis überflüssige Methode, die ganz schlicht um einen String herum noch HTML-Tags einbaut.

    Alternativ dazu kann man diese Tags auch manuell um den String bauen:

    str = "Hallo Welt";  
    document.write(str.small()); // Gibt "<small>Hallo Welt</small>" ins Dokument aus.  
    document.write("<small>".str."<\/small>"); // tut dasselbe.
    

    Der String "str" ist dabei nicht "formatiert". Einmal enthält er schlicht nur den Text, danach enthält er (als Parameter zu document.write(), aber man könnte das Ergebnis auch in eine neue Variable speichern) ganz schlicht Text umgeben von anderem Text, welcher aber das Aussehen von HTML-Tags hat.

    Was ich meine ist: Ich kenne aus anderen Sprachen, dass es den Datentyp "Richtext" gibt (den ich nicht gerne verwende, weil die Handhabung oft recht kompliziert und verwirrend ist). Und es gibt natürlich String/Zeichenkette.

    Ehrlich gesagt: Ich kenne solche Programmiersprachen nicht, was daran liegen könnte, dass ich primär PHP schreibe. Ich kenne aber sehr wohl die Tatsache, dass manche Sprachen für Desktop-Applikationen Dinge wie Rich-Text-Editorfelder anbieten, aus denen man sich die Formatierung dann ja irgendwie rauspulen muss. Das ist aber entweder ein komplexer Datentyp (man denke nur an einen XML-DOM-Baum), bei dem die Formatierung auf einem anderen Kanal übermittelt wird, als der eingegebene Text, oder es ist auch nur die Stringdarstellung des Textfeldes, bei dem die Formatierungskommandos entweder HTML, irgendeine Form von BBCode, oder irgendwelche ASCII-Sonderzeichen sind (wenn man sich mal alte Lineprinter-Dokus durchliest: Der Zeichenbereich ASCII 0 .. 31 wimmelt von Steuerzeichen, die die Druckausgabe beispielsweise auf "fett" oder "kursiv" stellen konnten - und es gibt keinen Grund, diese Steuerzeichen nicht auch heute noch zu verwenden - Tabulatoren werden ja auch noch verwendet).

    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").

    Das ist halt falsch. Diese "Formatierungs-Methoden" liefern dir immer nur den Originalstring mit drumrumgebauten HTML-Tags. Am Ende hast du immer wieder nur einen String - aber halt einen mit mehr Zeichen, der auch nur dann "formatiert" wird, wenn du ihn im HTML-Kontext in eine HTML-Seite packst. Wenn du ihn beispielsweise als Value einem Formularfeld zuweisen würdest, würde keine Formatierung wirksam werden, sondern die HTML-Tags drumherum sichtbar werden.

    Um es an einem Beispiel festzumachen: toLowerCase() ist eine typische Funktion (oder hier: Methode), die man auf Zeichenketten anwendet.
    sub() hingegen ist es idR nicht (Ausnahmen mögen Zeichen sein, die es im Unicode nochmal extra als tiefergestellt gibt).

    Nein, es gibt keine Ausnahme. sub() bastelt dir die Zeichenkette "<sub>" vor deinen String, und "</sub>" hinter deinen String. Ganz simpel. Und ziemlich überflüssig. Das brauchte man schon zu Zeiten von Netscape 3 nicht wirklich, und erst recht nicht heutzutage.

    toLowerCase() hingegen verändert die im String enthaltenen Zeichen, sofern es für sie eine in Unicode definierte Lower-Case-Variante gibt.

    Mein Problem bei der Sache ist halt, dass ich das gedanklich nicht auseinander bekomme. Woher weiß ich ob ich formatierten Text oder eine reine Zeichenkette erhalte, wenn ich z.B. einen Textknoten bzw. dessen Inhalt ergreife.

    Wenn du einen Textknoten mit DOM-Funktionen aufspürst, hast du immer simplen Text.

    Und wie gesagt, warum bietet mir "String" eine Methode namens "blink" anstatt dessen Elternelement.

    Weil die String-Methoden alle extrem blöd sind und vor der Entwicklung eines vernünftigen DOM (sprich: getElementById() etc.) in den Javascript-Standard aufgenommen wurden.

    Heutzutage würde man solche Funktionen nicht mehr in Javascript implementieren, und vermutlich würde man sie am liebsten wieder aus dem Standard entfernen.

    - Sven Rautenberg

    1. Danke Sven, mrjerk hatte mir das schon erklärt und ich hab's verstanden...

      Heutzutage würde man solche Funktionen nicht mehr in Javascript implementieren, und vermutlich würde man sie am liebsten wieder aus dem Standard entfernen.

      Ja, vielleicht sollte man das tun... ist ja ohnehin versioniert. Meinetwegen kann man anschließend auch die (eigentlich ebenso sinnfreie aber halt "quick and dirty") Methode .addTag("tagname", "attribut="wert""); (oder so) einführen.

      Zumindest scheinen wir uns alle einig zu sein, dass es grober Unsinn ist, weiterhin ignoriert werden sollte und äääh. Hmmm vielleicht sollte es auch weniger prominent in den JS-Dokumentationen stehen :-D

      Ohne hier eine Diskussion abwürgen zu wollen schreib ich jetzt doch mal ein "Antwort erhalten" in einen Posting-Titel.

      --
      sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ_de:] zu:) fl:( ss:| ls:[ js:(
  4. Sven und mrjerk haben mir den Sachverhalt eindeutig erklärt. Meine Verwirrung ist aufgehoben, ich danke.

    --
    sh:( fo:| ch:? rl:( br:& n4:& ie:{ mo:} va:) de:µ_de:] zu:) fl:( ss:| ls:[ js:(