juppinger: Text ersetzen

Hallo zusammen,

kann mir jemand helfen...

Ich habe einen Text innerhalb eines <SPAN>.

Beispiel:
--------------------------
<SPAN ID="meinText">
Dies ist ein Test mit einem <A HREF="Text.htm">Text</A>.
Dieser Text kann auch Bilder enthalten, z.B. <IMG SRC="text.jpg">.
</SPAN>
--------------------------

Nun möchte ich z.B. das Wort "Text" innerhalb des SPANs ersetzen mit dem Wort "Wortlaut".
Wichtig dabei ist jedoch, dass das Wort "Text" innerhalb eines A HREFs sowie <IMG> nicht ersetzt wird.

Also aus dem obigen Beispiel soll dann folgender Code werden ("Text" wird nur 1x ersetzt):
--------------------------
<SPAN ID="meinText">
Dies ist ein Test mit einem <A HREF="Text.htm">Text</A>.
Dieser Wortlaut kann auch Bilder enthalten, z.B. <IMG SRC="text.jpg">.
</SPAN>
--------------------------

Geht da was evtl. mit RegExpressions ?

Thx+gruss
juppinger

  1. Hallo Jupp !
    Das Ganze geht natürlich auch mit innerText :

    <script type="text/javascript">
    function wortwechsel ()
    {var wechsel = document.getElementById ("meinText");
    wechsel.innerHTML = "<SPAN>Dies ist ein Test mit einem <A HREF="javascript:wortwechsel2()">Text</A>. Dieser Wortlaut kann auch Bilder enthalten, z.B. <IMG SRC="text.jpg">.</SPAN>";
    }

    function wortwechsel2()
    {var wechsel = document.getElementById ("meinText");
    wechsel.innerHTML = "<SPAN>Dies ist ein Test mit einem <A HREF="javascript:wortwechsel()">Text</A>. Dieser Text kann auch Bilder enthalten, z.B. <IMG SRC="text.jpg">.</SPAN>";
    }
    </script>

    <span id="meinText">
    Dies ist ein Test mit einem <A HREF="javascript:wortwechsel()">Text</A>.
    Dieser Text kann auch Bilder enthalten, z.B. <IMG SRC="text.jpg">.
    </span>

    Spiel halt ein bißchen rum
    Gruß Frodo

  2. Hallo juppinger.

    Nun möchte ich z.B. das Wort "Text" innerhalb des SPANs ersetzen mit dem Wort "Wortlaut".
    […]
    Geht da was evtl. mit RegExpressions ?

    Es geht sogar ohne.

    „Text innerhalb eines Elementes aber nicht dessen Kindelemente ersetzen“
      Ein Rezept für jedermann

    Zutaten:

    • 1x Grundwissen über den Aufbau des Dokumentenbaumes im JS
      • Einige Methoden und Eigenschaften:
        • 1x http://de.selfhtml.org/javascript/sprache/eventhandler.htm#onload@title=onload
        • 1x getElement*
        • 1x (+3x) http://de.selfhtml.org/javascript/objekte/array.htm#length@title=length
        • 1x http://de.selfhtml.org/javascript/objekte/node.htm#child_nodes@title=childNodes
        • 1x http://de.selfhtml.org/javascript/objekte/node.htm#node_type@title=nodeType
        • 1x http://de.selfhtml.org/javascript/objekte/string.htm#replace@title=replace
      • 2x Variable oder Array, welche(r) die zu ersetzenden Werte und ihre Ersetzungen enthält

    Zubereitung:

    Man nehme http://de.selfhtml.org/javascript/objekte/document.htm#get_element_by_id@title=getElementById, http://de.selfhtml.org/javascript/objekte/document.htm#get_elements_by_tag_name@title=getElementsByTagName oder http://de.selfhtml.org/javascript/objekte/document.htm#get_elements_by_name@title=getElementsByName, um auf das jeweilige Element zuzugreifen. Natürlich müssen wir mit Hilfe von onload erst ein wenig warten, bis das Element bereit ist.
      Außerdem benutzen wir nun die beiden Variablen oder Arrays (falls wir uns zukünftig entscheiden sollten, weitere Werte aufzunehmen), um die Substitutionen festzulegen. Wenn wir bei den Arrays keine Unordnung hinterlassen wollen, so prüfen wir am Besten vor der Benutzung mit length, ob ihre Länge übereinstimmt.
      Wurden alle Vorbereitungen getroffen, können wir uns nun an die eigentlichen Arbeitsschritte wagen.
      Als erstes durchlaufen wir mit einer Schleife und childNodes alle Kindelemente des Elementes, auf das wir uns am Anfang Zugriff verschafft haben. In dieser Schleife fragen wir nun ab, ob der nodeType des Kindelementes mit der Zahl 3 (Textknoten) übereinstimmt. Ist dies der Fall, so ersetzen wir mit nodeValue und replace im Wert des Textknoten die Zeichenkette(n) durch ihre Ersetzunge(n), welche wir Anfangs festgelegt hatten.
      Haben wir uns für die Array-Methode entschieden, so fügen wir in der Abfrage noch eine weitere Schleife hinzu, welche alle Elemente im Array, in dem die zu ersetzenden Zeichenketten festgelegt wurden, mittels replace durch die passenden Gegenstücke ersetzt.
      Das ganze lassen wir nun im gut vorgewärmten Browser durchlaufen.

    Bon Appetite!

    Einen schönen Donnerstag noch.

    Gruß, Ashura

    --
    *narf*
    1. Hallo Ashura,

      vielen herzlichen Dank für Dein perfektes Rezept.
      Ich habe es soweit auch umgesetzt - schmneckt sehr fein :)

      Ein Problem hab ich aber noch. Wenn ich den zu ersetzenden Text mit einer URL versehe, so schreibt er die URL als Text aus und erzeugt keinen wirklichen A HREF.

      Mein Code, bitte bitte hilf mir doch nochmal:

      <span id="IAMtext">Dies ist ein Text mit einem <a href="#">Text</a>, dieser Test ist gut.<br>Es gibt auch ein Bild mit einem Auto.</span>

      <script>
      var Keywords_Keys = new Array(
             "Text",
             "Auto"
                    );

      var Keywords_Urls = new Array(
             "<a href="http://www.texts.de">Text</a>",
             "<a href="http://www.auto.de">Auto</a>"
                    );

      var Anzahl = document.getElementById("IAMtext").childNodes.length;
      var Pos = -1;
      var Text = "";
      var TextNeu = "";

      for(x=0;x<Keywords_Keys.length;x++) {
      for(i=0;i<Anzahl;i++) {
       if(document.getElementById("IAMtext").childNodes[i].nodeType == 3) {
        // Text aus ChildNode auslesen
        Text = document.getElementById("IAMtext").childNodes[i].data;
        // Text ersetzen
              Pos = Text.indexOf(Keywords_Keys[x], 0);
        if(Pos >= 0) {
         TextNeu = Text.replace(Keywords_Keys[x], Keywords_Urls[x]);
         document.getElementById("IAMtext").childNodes[i].nodeValue = TextNeu;
        }
       }
      }
      }
      </script>

      ========================================================
      Danke + Gruss
      juppinger

      Hallo juppinger.

      Nun möchte ich z.B. das Wort "Text" innerhalb des SPANs ersetzen mit dem Wort "Wortlaut".
      […]
      Geht da was evtl. mit RegExpressions ?

      Es geht sogar ohne.

      „Text innerhalb eines Elementes aber nicht dessen Kindelemente ersetzen“
        Ein Rezept für jedermann

      Zutaten:

      • 1x Grundwissen über den Aufbau des Dokumentenbaumes im JS
        • Einige Methoden und Eigenschaften:
          • 1x http://de.selfhtml.org/javascript/sprache/eventhandler.htm#onload@title=onload
          • 1x getElement*
          • 1x (+3x) http://de.selfhtml.org/javascript/objekte/array.htm#length@title=length
          • 1x http://de.selfhtml.org/javascript/objekte/node.htm#child_nodes@title=childNodes
          • 1x http://de.selfhtml.org/javascript/objekte/node.htm#node_type@title=nodeType
          • 1x http://de.selfhtml.org/javascript/objekte/string.htm#replace@title=replace
        • 2x Variable oder Array, welche(r) die zu ersetzenden Werte und ihre Ersetzungen enthält

      Zubereitung:

      Man nehme http://de.selfhtml.org/javascript/objekte/document.htm#get_element_by_id@title=getElementById, http://de.selfhtml.org/javascript/objekte/document.htm#get_elements_by_tag_name@title=getElementsByTagName oder http://de.selfhtml.org/javascript/objekte/document.htm#get_elements_by_name@title=getElementsByName, um auf das jeweilige Element zuzugreifen. Natürlich müssen wir mit Hilfe von onload erst ein wenig warten, bis das Element bereit ist.
        Außerdem benutzen wir nun die beiden Variablen oder Arrays (falls wir uns zukünftig entscheiden sollten, weitere Werte aufzunehmen), um die Substitutionen festzulegen. Wenn wir bei den Arrays keine Unordnung hinterlassen wollen, so prüfen wir am Besten vor der Benutzung mit length, ob ihre Länge übereinstimmt.
        Wurden alle Vorbereitungen getroffen, können wir uns nun an die eigentlichen Arbeitsschritte wagen.
        Als erstes durchlaufen wir mit einer Schleife und childNodes alle Kindelemente des Elementes, auf das wir uns am Anfang Zugriff verschafft haben. In dieser Schleife fragen wir nun ab, ob der nodeType des Kindelementes mit der Zahl 3 (Textknoten) übereinstimmt. Ist dies der Fall, so ersetzen wir mit nodeValue und replace im Wert des Textknoten die Zeichenkette(n) durch ihre Ersetzunge(n), welche wir Anfangs festgelegt hatten.
        Haben wir uns für die Array-Methode entschieden, so fügen wir in der Abfrage noch eine weitere Schleife hinzu, welche alle Elemente im Array, in dem die zu ersetzenden Zeichenketten festgelegt wurden, mittels replace durch die passenden Gegenstücke ersetzt.
        Das ganze lassen wir nun im gut vorgewärmten Browser durchlaufen.

      Bon Appetite!

      Einen schönen Donnerstag noch.

      Gruß, Ashura

      1. Hallo juppinger.

        Vorweg: bitte kein TOFU, danke.

        vielen herzlichen Dank für Dein perfektes Rezept.
        Ich habe es soweit auch umgesetzt - schmneckt sehr fein :)

        Das hört man gern.

        Ein Problem hab ich aber noch. Wenn ich den zu ersetzenden Text mit einer URL versehe, so schreibt er die URL als Text aus und erzeugt keinen wirklichen A HREF.

        Du hast eine der Zutaten nicht gänzlich berücksichtigt: „Grundwissen über den Aufbau des Dokumentenbaumes im JS“. Du möchtest keine HTML-Link-ähnliche Zeichenkette einfügen, sondern eine Zeichenkette durch einen vollwertigen Elementknoten ersetzen.

        Um dir hier einen unnötigen Aufwand zu ersparen, solltest du in diesem Falle mit innerHTML arbeiten. Die hiermit eingefügten Zeichenketten werden als HTML interpretiert.
        Andernfalls müsstest du die gesamte Zeichenkette einlesen, am Schlüsselwort http://de.selfhtml.org/javascript/objekte/string.htm#split@title=aufteilen, beide Teile der Zeichenkette <http://de.selfhtml.org/javascript/objekte/document.htm#create_text_node@title=zu Textknoten machen> und schließlich zuerst den ersten Teil der Zeichenkette, dann den Elementknoten und schließlich den zweiten Teil der Zeichenkette wieder <http://de.selfhtml.org/javascript/objekte/node.htm#append_child@title=in das Elternelement einfügen>.

        var Keywords_Keys = new Array(

        "Text",
               "Auto"
                      );

          
        Hier gibt es eine (meiner Meinung nach übersichtlichere) Kurzschreibweise für Arrays:  
          
        `var Keywords_Keys = ["Text", "Auto"];`{:.language-javascript}  
          
        [] ist hier also äquivalent zu new Array()  
          
        
        > ~~~javascript
        
        var Keywords_Urls = new Array(  
        
        >        "<a href=\"http:\/\/www.texts.de\">Text</a>",  
        >        "<a href=\"http:\/\/www.auto.de\">Auto</a>"  
        >               );
        
        

        Wenn du weißt, welche Quotes innerhalb einer Zeichenkette vorkommen können, kannst du die jeweils andere wählen und dir damit etwas Maskiererei ersparen:

        var Keywords_Urls = ['<a href="http://www.texts.de">Text</a>', <a href="http://www.auto.de">Auto</a>']

        (Das Maskieren der Slashes ist hier im übrigen gar nicht erforderlich.)

        for(x=0;x<Keywords_Keys.length;x++) {

        Auch innerhalb von Schleifen solltest du vom Schlüsselwort „var“ Gebrauch machen:

        for (var x = 0; x < Keywords_Keys.length; x++) {}

        for(i=0;i<Anzahl;i++) {

        if(document.getElementById("IAMtext").childNodes[i].nodeType == 3) {

          
        Wenn du hier:  
          
        `var Anzahl = document.getElementById("IAMtext").childNodes.length;`{:.language-javascript}  
          
        lediglich die Referenz auf das Objekt ablegen würdest, könntest du diese in deiner Schleife immer wieder verwenden.  
          
        Folgendes würde sich also ändern:  
          
        Aus `var Anzahl = document.getElementById("IAMtext").childNodes.length;`{:.language-javascript} würde `var myElement = document.getElementById("IAMtext");`{:.language-javascript}, aus `for(i=0;i<Anzahl;i++)`{:.language-javascript} würde `for (var i = 0; i < myElement.childNodes.length; i++)`{:.language-javascript} und aus `if(document.getElementById("IAMtext").childNodes[i].nodeType == 3)`{:.language-javascript} würde ganz einfach `if (myElement.childNodes[i].nodeType === 3)`{:.language-javascript}. (Beachte auch, dass ich hier nun den Identitätsoperator an Stelle des <http://de.selfhtml.org/javascript/sprache/operatoren.htm#vergleich@title=Vergleichsoperators> verwendet habe. Dieser prüft zusätzlich zum Wert noch auf exakte Typengleichheit; hier also darauf, ob der Wert von nodeType auch dem Typ „Number“ entspricht.)  
          
        
        >   ~~~javascript
        
        // Text aus ChildNode auslesen  
        
        >   Text = document.getElementById("IAMtext").childNodes[i].data;  
        >   // Text ersetzen  
        >         Pos = Text.indexOf(Keywords_Keys[x], 0);  
        >   if(Pos >= 0) {
        
        

        Die Überprüfung ist eigentlich nicht erforderlich. Wenn das jeweilige Schlüsselwort nicht gefunden wurde, kann es logischerweise auch nicht ersetzt werden.

        TextNeu = Text.replace(Keywords_Keys[x], Keywords_Urls[x]);
           document.getElementById("IAMtext").childNodes[i].nodeValue = TextNeu;

        Hier genügt also vollkommen Folgendes:

        myElement.nodeValue = myElement.nodeValue.replace(Keywords_Keys[x], Keywords_Urls[x]);

        Einen schönen Donnerstag noch.

        Gruß, Ashura

        --
        *narf*
        1. Hallo Ingrid.

          Um dir hier einen unnötigen Aufwand zu ersparen, solltest du in diesem Falle mit http://de.selfhtml.org/javascript/objekte/all.htm#inner_html@title=innerHTML arbeiten. Die hiermit eingefügten Zeichenketten werden als HTML interpretiert.

          Ich wollte innerHTML noch verlinkt haben.

          var Keywords_Urls = ['<a href="http://www.texts.de">Text</a>', '<a href="http://www.auto.de">Auto</a>']

          Hier fehlte natürlich das eröffnende Anführungszeichen beim zweiten Element im Array.

          Einen schönen Donnerstag noch.

          Gruß, Ashura

          --
          *narf*
        2. Hallo Ashura,

          nochmal vielen vielen Dank für Deine suuuper 1a-perfekte Unterstützung. Sowas Gutes findet man recht selten im Netz! (Jemanden, der sich so einer Sache annimmt, um anderen zu helfen). Respekt und Hut ab!!!

          Eine (hoffentlich) letzt Frage:

          Um dir hier einen unnötigen Aufwand zu ersparen, solltest du in diesem Falle mit innerHTML arbeiten. Die hiermit eingefügten Zeichenketten werden als HTML interpretiert.

          Könntest Du mir hierzu ein konkretes Beispiel (am Besten anhand meines Codes) geben?

          1000-Dank &
          gruß
          juppinger

          1. Hallo juppinger.

            Um dir hier einen unnötigen Aufwand zu ersparen, solltest du in diesem Falle mit innerHTML arbeiten. Die hiermit eingefügten Zeichenketten werden als HTML interpretiert.

            Könntest Du mir hierzu ein konkretes Beispiel (am Besten anhand meines Codes) geben?

            Das kannst du nun alleine genau so gut hinbekommen.

            Verschaffe dir einmal wie gehabt Zugriff auf das jeweilige Element und lasse dir dessen innerHTML-Eigenschaft ausgeben.

            Also:

            var myElement = document.getElementById("IAMtext");  
              
            alert(myElement.innerHTML);
            

            Damit sollte dir eigentlich klar sein, was du damit anfangen kannst. Du gehst hier mit innerHMTL ebenso um, wie du es mit nodeValue getan hast. Wie gesagt ist der für dich einzig relevante Unterschied, dass das HTML in Zeichenketten bei innerHTML interpretiert wird.

            Einen schönen Donnerstag noch.

            Gruß, Ashura

            --
            *narf*
            1. Hallo,

              bin so langsam am verzweifeln. Ich raffs einfach nicht.

              document.getElementById("IAMtext").childNodes[i].innerHTML = TextNeu;

              --> Klappt nicht :-(

              Ich verstehe das nicht.

              Genauso klappt
              document.getElementById("IAMtext").childNodes[i].nodeValue.innerHTML = TextNeu;
              nicht!

              Sorry. Kannst Du mir da behilflich sein, biiittteeee ?

              Stehe VOLL auf dem Schlauch!

              1. Hallo juppinger.

                bin so langsam am verzweifeln. Ich raffs einfach nicht.

                document.getElementById("IAMtext").childNodes[i].innerHTML = TextNeu;

                Warum nicht so:

                document.getElementById("IAMtext").childNodes[i].innerHTML = document.getElementById("IAMtext").childNodes[i].innerHTML.replace('foo', '<a href="http://example.org/">Example</a>');

                Das Problem hieran ist natürlich, dass innerHTML stur alles durchsucht. Kindelemente gibt es für innerHTML nicht, lediglich interpretierte Zeichenketten.

                --> Klappt nicht :-(

                Das ist keine brauchbare Fehlerbeschreibung.

                Einen schönen Freitag noch.

                Gruß, Ashura

                --
                sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                mathbr:del.icio.us/ mathbr:w00t/
                1. Hallo Ashura,

                  schön von Dir zu hören und von Deinen Kochkünsten partizipieren zu können :-)

                  Wenn ich
                  document.getElementById("IAMtext").childNodes[i].innerHTML.replace('foo', '<a href="http://example.org/">Example</a>');

                  anwende, kommt die Meldung:
                  'document.getElementById(...)childNodes[...].innerHTML' ist Null oder kein Objekt'

                  :-(

                  Was könnte das denn nun sein?

                  1000-Dank im Voraus.

                  Mein aktueller Code:

                  <span id="IAMtext">Dies ist ein Text mit einem <a href="#">Text</a>, dieser Test ist gut.<br>Es gibt auch ein Bild mit einem Auto.</span>

                  <script type="text/javascript">
                  var Keywords_Keys = ["Text", "Auto"];

                  var Keywords_Urls = ['<a href="http://www.texts.de">Text</a>', '<a href="http://www.auto.de">Auto</a>'];

                  var myElement = document.getElementById("IAMtext");
                  var Text = "";

                  for(var x=0;x<Keywords_Keys.length;x++) {
                  for(var i=0;i<myElement.childNodes.length;i++) {
                   if(myElement.childNodes[i].nodeType === 3) {
                    // Text aus ChildNode auslesen
                    Text = myElement.childNodes[i].data;
                    // Text ersetzen
                    myElement.childNodes[i].innerHTML.replace(Keywords_Keys[x], Keywords_Urls[x]);
                   }
                  }
                  }
                  </script>

                  1. Hallo juppinger.

                    Was könnte das denn nun sein?

                    Also gut, schauen wir uns einmal an, was wir nun haben und was man daraus machen kann.

                    var Text = "";

                    […]
                    Text = myElement.childNodes[i].data;

                      
                    Du hast doch gar keinen Verwendungszweck für die Variable Text mehr, wenn innerHTML nutzt. Also trenne dich davon.  
                      
                    
                    > ~~~javascript
                    
                    for(var x=0;x<Keywords_Keys.length;x++) {  
                    
                    > for(var i=0;i<myElement.childNodes.length;i++) {  
                    >  if(myElement.childNodes[i].nodeType === 3) {  
                    >   // Text aus ChildNode auslesen  
                    >   Text = myElement.childNodes[i].data;  
                    >   // Text ersetzen  
                    >   myElement.childNodes[i].innerHTML.replace(Keywords_Keys[x], Keywords_Urls[x]);  
                    >  }  
                    > }  
                    > }
                    
                    

                    Die gesamte innere Schleife ist mit innerHTML überflüssig geworden.
                    Du möchtest:

                    Für jedes Schlüsselwort
                      den Wert von innerHTML durch sein präpariertes (also per replace-Methode behandeltes) Double ersetzen.

                    Das ist alles. Wie gesagt schert sich innerHTML nicht wirklich um den Dokumentenbaum, weshalb es dort auch keine Knoten gibt.

                    Einen schönen Freitag noch.

                    Gruß, Ashura

                    --
                    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                    mathbr:del.icio.us/ mathbr:w00t/
                    1. Hallo Ashura,

                      Für jedes Schlüsselwort
                        den Wert von innerHTML durch sein präpariertes (also per replace-Methode behandeltes) Double ersetzen.

                      ... und da wären wir wieder bei meinem Problem:
                      Wenn ich in dem innerHTML eine URL oder ein IMG mit gleichem zu ersetzenden Wert habe, würde dieses leider auch mit ersetzt werden.

                      Wenn z.B. "Auto" durch "<a href='http://www.auto.de'>Auto</a>" ersetzt werden würde, so würde er mir bei folgendem Text auch das IMG ersetzen. Dies genau soll aber nicht passieren...:

                      <span id="IAMtext">Das Wort Auto soll ersetzt werden. Der IMG-Src aber nicht: <img src="Auto.jpg></span>

                      Gruss
                        juppinger

                      1. Hallo juppinger.

                        Wenn ich in dem innerHTML eine URL oder ein IMG mit gleichem zu ersetzenden Wert habe, würde dieses leider auch mit ersetzt werden.

                        Ja, das ist, wie ich schon schrieb, ein Nachteil von innerHTML; es berücksichtigt keine Elementknoten.

                        Dafür gibt es meines Wissens keine Lösung, du solltest also abwägen, was dir wichtiger erscheint: eine einfache Umsetzung (innerHTML) oder maximale Kontrolle (DOM).

                        Einen schönen Montag noch.

                        Gruß, Ashura

                        --
                        sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
                        mathbr:del.icio.us/ mathbr:w00t/
            2. Ashura, erbitte erneut Deine Hilfe.