Ingo Turski: innerHTML und Zeilenumbrüche im Quelltext in <pre>

Hi,

ich brüte gerade an einem kleinem Zusatzfeature, das ich meiner Statistik-Seite spendieren möchte.
Beim Aktualisieren der Seite kopiere ich die Daten z.Z. noch als unformatierten Text in ein PRE-Element, um mir das manuelle Einfügen von BRs zu ersparen. Jetzt wollte ich über Javascript die hier enthaltenen URLs verlinken. Hierzu lese ich den Inhalt des PRE über innerHTML in eine Variable, suche mir die URLs raus und umgebe sie mit Links.

Wenn ich nun die neue Varable wieder über innerHTML in das PRE-Element setze, dann fehlen mir die Zeilenumbrüche; innerHTML nimmt ja hierfür nur ein Whitespace auf.

Gibt es irgendeine Möglichkeit, die Zeilenumbrüche im Quelltext auszulesen bzw. zu erkennen, um dann an diesen Stellen BRs einzufügen?

freundliche Grüße
Ingo

  1. hi,

    Gibt es irgendeine Möglichkeit, die Zeilenumbrüche im Quelltext auszulesen bzw. zu erkennen, um dann an diesen Stellen BRs einzufügen?

    die replace-methode des string-objektes sollte weiterhelfen.
    allerdings ersetzt die immer nur das erste vorkommen, deshalb muss man sie ggf. mehrmals aufrufen.

    while(deinstring.match(/\n/)) {
      deinstring = deinstring.replace(/\n/, "<br>");
    }

    gruß,
    wahsaga

    --
    "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
    1. Hi,

      allerdings ersetzt die immer nur das erste vorkommen, deshalb muss man sie ggf. mehrmals aufrufen.

      Also wenn das kein Grund ist, "wah" zu sagen ... =;-o

      Gruß, Cybaer

      --
      Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
    2. Hi,

      while(deinstring.match(/\n/)) {
        deinstring = deinstring.replace(/\n/, "<br>");
      }

      danke. Funktioniert prima.

      Wie ich jetzt festgestellt habe, betrifft dieses Problem nur den IE und der macht trotzdem noch Probleme bei mehreren aufeinanderfolgenden Zeilenumbrüchen sowie bei mehreren Leerzeichen hintereinander.

      Aber das habe ich jetzt auch hinbekommn über:

      if(window.external) {
            while(y.match(/\n/)) { y = y.replace(/\n/, '&nbsp;<br>'); }
            while(y.match(' ')) { y = y.replace(' ', '&nbsp;'); }
          }

      Aber trotzdem noch eine andere Frage hierzu: gibt es auch eine Möglichkeit, den Inhalt des Quelltextes gleich zeilenweise in ein Array zu bekommen?

      freundliche Grüße
      Ingo

      1. hi,

        Aber trotzdem noch eine andere Frage hierzu: gibt es auch eine Möglichkeit, den Inhalt des Quelltextes gleich zeilenweise in ein Array zu bekommen?

        wenn du ihn bereits in einen string vorliegen hast, könntest du ja einfach split() darauf anwenden.

        gruß,
        wahsaga

        --
        "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
        1. Hi,

          wenn du ihn bereits in einen string vorliegen hast, könntest du ja einfach split() darauf anwenden.

          nochmal danke, funktioniert - hätte ich ja eigentlich jetzt selbst drauf kommen müssen. ;-)
          Allerdings muß ich split() auf die Variable anwenden, die den Inhalt von innerHTML "im Original" erhält. Bei Anwendung auf eine weitere, hieraus zusammensetzte Variable verhält sich Firefox sehr merkwürdig.
          Und für den IE darf ich das </pre> nicht in eine neue Zeile setzen, weil er sonst ein Element mehr zählt.

          freundliche Grüße
          Ingo

          1. hi,

            Allerdings muß ich split() auf die Variable anwenden, die den Inhalt von innerHTML "im Original" erhält. Bei Anwendung auf eine weitere, hieraus zusammensetzte Variable verhält sich Firefox sehr merkwürdig.

            und merkwürdig heißt ...? ;-)

            grundsätzlich könnte es probleme damit geben, dass der gecko was die knotenstruktur angeht bei text mit umbrüchen etwas anderer ansicht ist als der IE. für den gecko beginnt nach einem zeilenumbruch ein neuer textknoten, IIRC.

            Und für den IE darf ich das </pre> nicht in eine neue Zeile setzen, weil er sonst ein Element mehr zählt.

            ich weiß nicht, wie nah dein eingangsbeispiel an der realen situation war, aber wenn du zunächst nur den textinhalt brauchst, wäre auslesen über innerText evtl. eine alternative (sofern der gecko das ebenfalls adaptiert hat?), bei der dir die probleme mit den knoten u.U. erst mal erspart bleiben.

            gruß,
            wahsaga

            --
            "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
            1. Hi,

              Allerdings muß ich split() auf die Variable anwenden, die den Inhalt von innerHTML "im Original" erhält. Bei Anwendung auf eine weitere, hieraus zusammensetzte Variable verhält sich Firefox sehr merkwürdig.

              und merkwürdig heißt ...? ;-)

              schwer zu erklären. Ich poste am besten mal den Code:
              Es geht um den Inhalt der Seite http://www.1ngo.de/statistik.html#Aktuelles nach der Zeile "Auszüge meiner Statistik für den Monat November 2004", der in <pre id="Verweise"> </pre> gesetzt ist.
              Hierauf greife ich bis jetzt onload so zu:

              function Verweise() {
                  var x=document.getElementById('Verweise').innerHTML, y='', p0=0, p1, i, v;
                  p1 = x.indexOf('* /')+2; // da wird später eine intelligentere Schleife draus
                  y += x.slice(p0,p1); p0 = p1;
                  do { p1++; } while (x.charCodeAt(p1) > 32); // das kann ich mir bei einem Array sparen
                  v = x.slice(p0,p1);
              alert(v); alert(v.link(v)); // liefern in Kombination korrekte Ergebnisse
                  y += v.link(v);
                  p0 = p1+1; y += x.slice(p0);
                  if(window.external) { // korrigiert die Fehler im IE
                    y = y.replace(/\n/g, '&nbsp;<br>');
                    y = y.replace(/ /g, '&nbsp;');
                  }
                  document.getElementById('Verweise').innerHTML = y;
                }

              Im Firefox funktioniert das jetzt so und die erste der »Top20 Einstiegsseiten« wird verlinkt.
              Im IE mußte ich leider gerade feststellen, daß die Verlinkung nicht klappt. :-(

              Jetzt das merkwürdige. Ohne den hinzugefügten alert(v) setzt Firefox über v.link(v) den gesamten Rest der Variablen x in den Link, gibt das im alert auch aus und setzt es als Linkziel im anschließend neugeschriebenem innerHTML ein. Daduch bekommt ein später definiertes Array var z = y.split(/\n/) statt 204 nun 331 Elemente, das Element 76 den Inhalt »2853* <a href="/tanz/tanzschritte.html«, das eigentlch letzte Element 203 den Inhalt »...">/tanz/tanzschritte.html</a>« und die eigentlich nicht mehr vorhandenen weiteren Elemente die folgenden Zeilen.

              ich weiß nicht, wie nah dein eingangsbeispiel an der realen situation war, aber wenn du zunächst nur den textinhalt brauchst, wäre auslesen über innerText evtl. eine alternative (sofern der gecko das ebenfalls adaptiert hat?), bei der dir die probleme mit den knoten u.U. erst mal erspart bleiben.

              ach, ich  glaube, mit innerHTML bin ich auf der sicheren Seite...

              Ich probiere das jetzt mal mit zeilenweiser Abarbeitung nach split() und muß dann nur noch herausfinden, ob der Firefox auch dann noch ein alert (oder vielleicht timeout) braucht und ob der IE die Links dann über innerHTML zurckschreibt.

              freundliche Grüße
              Ingo

              1. Hi,

                ich habe das Script jetzt fertig und in http://www.1ngo.de/statistik.html#Aktuelles integriert. Es verlinkt die internen URLs der "Auszüge meiner Statistik für den Monat November 2004" im IE, Firefox und Opera - leider aber nicht im Mozilla 1.7.3.
                Hat vielleicht jemand eine Idee, woran es bei dem hapern könnte?

                Das onload aufgerufene Script:

                function Verweise() {
                  var x = document.getElementById('Verweise').innerHTML, y = '';
                  var a0 = '<a href="', a1 = '">', a2 = '<'+'/a>';
                  var z = x.split(/\n/);
                  for (var i=0; i<z.length; i++) {
                    var p = z[i].indexOf('* /');
                    if(p!=-1) {
                      var t = z[i].slice(0,p+2); var v = z[i].slice(p+2);
                      if(v.indexOf(' ')==-1) {
                        if(window.external) z[i] = t.replace(/ /g, '&nbsp;') + v.link(v) + '<br>';
                        else z[i] = t + a0 + v + a1 + v + a2;
                      }
                      else if(window.external) z[i] = z[i].replace(/ /g, '&nbsp;') + '<br>';
                    }
                    else if(window.external) z[i] = z[i].replace(/ /g, '&nbsp;') + '&nbsp;<br>';
                    y += z[i];
                  }
                  document.getElementById('Verweise').innerHTML = y;
                }

                Der Firefox hatte wie schon gesagt v.link(v) nicht umgesetzt ohne einen Stop über alert(). Daher die umständliche Einfügung der Link-Tags. Im IE wiederum funktionierte ausschließlich die Methode über link() und auch nur dann, wenn der String in einer einzigen Anweisung zusammengesetzt wurde - schon sehr merkwürdig.

                freundliche Grüße
                Ingo

                1. Hat vielleicht jemand eine Idee, woran es bei dem hapern könnte?

                  Nach langem testen bin ich auf eine Lösung gekommen:

                  function Verweise() {

                  var o = document.getElementById('Verweise');
                    var text = o.innerHTML

                  var n = text.replace( /\*./([^\012\015]*)/g, '* <a href="$1">/$1</a>');
                    if(o.outerHTML )
                    {
                          n = n.replace( /\n/g, '<br>\n');
                          o.outerHTML = '<pre>' + n + '</pre>';
                    }
                    else o.innerHTML = n;

                  return;
                  }

                  Struppi.

                  1. Nach langem testen bin ich auf eine Lösung gekommen:

                    Nur Opera zickt rum. JS macht zwar alles aber er zeigt nichts an.

                    Getestet:
                    IE 6
                    MZ 1.6
                    FF 1.0

                    Läuft nicht:
                    OP 7.2

                    alles unter WinXP

                    Struppi.

                  2. Hi,

                    Nach langem testen bin ich auf eine Lösung gekommen:

                    wow... danke. Sieht aber kompliziert aus. ;-)

                    var n = text.replace( /\*./([^\012\015]*)/g, '* <a href="$1">/$1</a>');

                    Puh, was macht die RegExp hier genau? Leider fehlt noch der Ausschluß von Spaces im URL-Teil (siehe das manuell verlinkte "[-> Forum]".

                    if(o.outerHTML )
                      {
                            n = n.replace( /\n/g, '<br>\n');
                            o.outerHTML = '<pre>' + n + '</pre>';
                      }

                    In Opera 7.54 funktioniert das übrigens, allerdings werden Leerzeilen eingefügt. Ich habe mal ergänzt auf:
                    if(o.outerHTML && !window.opera)

                    denn Opera (zumindest 7.54) kommt auch mit Deinem

                    else o.innerHTML = n;

                    klar. Wie's bei älteren Operas aussieht, kann ich jetzt leider nicht testen.

                    freundliche Grüße
                    Ingo

                    1. Nach langem testen bin ich auf eine Lösung gekommen:
                      wow... danke. Sieht aber kompliziert aus. ;-)

                      ich fand dein Ansatz komplizierter ;-)

                      var n = text.replace( /\*./([^\012\015]*)/g, '* <a href="$1">/$1</a>');
                      Puh, was macht die RegExp hier genau? Leider fehlt noch der Ausschluß von Spaces im URL-Teil (siehe das manuell verlinkte "[-> Forum]".

                      Ja, ganz einfach:
                      var n = text.replace( /\*./([^\012\015 ]*)/g, '* <a href="$1">/$1</a>');

                      die ist relativ simpel (ich bin nicht besonders in RegExp)

                      such ein * und ein x-beliebiges Zeichen und ein /
                      (das mit dem x-beliebigen Zeichen weil die Leerzeichen irgendwie im Firefox nicht gepaßt haben)
                      und danach alle Zeichen die keine Zeilenumbrüche sind und die werden in der spezialvariabel $1 abgespeichert und dann entsprechend alles ersetzen.

                      denn Opera (zumindest 7.54) kommt auch mit Deinem

                      else o.innerHTML = n;
                      klar. Wie's bei älteren Operas aussieht, kann ich jetzt leider nicht testen.

                      Tja, wie gesagt 7.11 scheint nicht zu gehen (zumindest zegt er nichts an, weder outer noch bei inner

                      Struppi.

                      1. Hi,

                        ich fand dein Ansatz komplizierter ;-)

                        hehe.. ich würde eher umständlicher sagen.

                        var n = text.replace( /\*./([^\012\015]*)/g, '* <a href="$1">/$1</a>');
                        Puh, was macht die RegExp hier genau? Leider fehlt noch der Ausschluß von Spaces im URL-Teil (siehe das manuell verlinkte "[-> Forum]".

                        Ja, ganz einfach:
                        var n = text.replace( /\*./([^\012\015 ]*)/g, '* <a href="$1">/$1</a>');

                        dann wird aber der String vor dem Leerzeichen verlinkt. Ich wollte eigentlich die ganze Zeile ausschließen, aber eigentlich ist es sogar logischer, auch die Grafik zu verlinken.
                        Nur mal interessehalber: (wie) könnte man die Zeile mit Leerzeichen vom Ersetzen (einfach) ausschließen?

                        und danach alle Zeichen die keine Zeilenumbrüche sind

                        hmm.. die Codes 012 und 015. Da war ich drüber gestolpert, weil die dezimale Entsptrechung für 0a 0d doch 010 und 013 wäre (?)

                        Tja, wie gesagt 7.11 scheint nicht zu gehen (zumindest zegt er nichts an, weder outer noch bei inner

                        Naja, da der ja nun wirklich nicht mehr oft eingesetzt werden dürfte, ist das zu verschmerzen - zumal es ja ohnehin nur ein Gimmick ist.

                        freundliche Grüße
                        Ingo

                        1. ich fand dein Ansatz komplizierter ;-)
                          hehe.. ich würde eher umständlicher sagen.

                          Zuerst hatte ich auch versucht das zu optimieren (dieser komische v.link(v) Bug hat mich gereizt, aber keine Chance), bis mir dann irgendwann auffiel das evtl.  eine RegExp in Frage kommt. Und dann ers'mal gesucht da selfhtml da leider keine Hilfe ist.

                          var n = text.replace( /\*./([^\012\015]*)/g, '* <a href="$1">/$1</a>');
                          Puh, was macht die RegExp hier genau? Leider fehlt noch der Ausschluß von Spaces im URL-Teil (siehe das manuell verlinkte "[-> Forum]".

                          Ja, ganz einfach:
                          var n = text.replace( /\*./([^\012\015 ]*)/g, '* <a href="$1">/$1</a>');
                          dann wird aber der String vor dem Leerzeichen verlinkt. Ich wollte eigentlich die ganze Zeile ausschließen, aber eigentlich ist es sogar logischer, auch die Grafik zu verlinken.
                          Nur mal interessehalber: (wie) könnte man die Zeile mit Leerzeichen vom Ersetzen (einfach) ausschließen?

                          Wahrscheinlich, aber wie gesagt meine Kenntnisse sind da leider auch nicht ausgereift.

                          und danach alle Zeichen die keine Zeilenumbrüche sind
                          hmm.. die Codes 012 und 015. Da war ich drüber gestolpert, weil die dezimale Entsptrechung für 0a 0d doch 010 und 013 wäre (?)

                          eigentlich müßte ja '\n' reichen, aber offensichtlich gibt es da Probleme. Unter Windows (DOS) ist ein Zeilenumbruch ja \012\015 aber anscheinend (ich hab das jetzt nicht lang getestet) sieht das die RegExp Engine von Firefox anders oder ... ich weiß es nicht wirklich warum es mit \n nicht geklappt hat.

                          aber die Methode ist sowieso sauberer, da sie die Umbrüch auf allen System findet

                          Struppi.

                          1. Hi,

                            Zuerst hatte ich auch versucht das zu optimieren (dieser komische v.link(v) Bug hat mich gereizt, aber keine Chance)

                            mich auch ;-) aber eine Notlösung über - wenn auch kurze - Programmunterbrechung wäre wohl kaum praktikabel gewesen.
                            Interessant, daß der IE bei der outerHTML-Version keine Probleme mit den Ersetzungen macht. Meine Lösung funktionierte beim IE nur mit link().

                            eigentlich müßte ja '\n' reichen, aber offensichtlich gibt es da Probleme. Unter Windows (DOS) ist ein Zeilenumbruch ja \012\015

                            Jetzt fällt mir ein, daß es ja auch noch das Oktalsystem gibt..;-)
                            Vielleicht würde aber auch \n\r funktionieren.

                            freundliche Grüße
                            Ingo

      2. Hi,

        while(y.match(/\n/)) { y = y.replace(/\n/, '&nbsp;<br>'); }

        Wah! (again ;-))

        replace(/\n/g ...

        Das "g" sorgt dafür, daß *alle* Vorkommnisse ersetzt werden, nicht nur das erste!

        Aber trotzdem noch eine andere Frage hierzu: gibt es auch eine Möglichkeit, den Inhalt des Quelltextes gleich zeilenweise in ein Array zu bekommen?

        source=y.split("\n");?

        Gruß, Cybaer

        --
        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
        1. hi,

          Wah! (again ;-))

          replace(/\n/g ...
          Das "g" sorgt dafür, daß *alle* Vorkommnisse ersetzt werden, nicht nur das erste!

          war mir wohl entgangen, benutze regex in JS so gut wie nie.

          gruß,
          wahsaga

          --
          "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
          1. Hi,

            war mir wohl entgangen, benutze regex in JS so gut wie nie.

            Ist in JS auch nicht anders als sonst. ;-)

            Gruß, Cybaer

            --
            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!