Gina: Daten eines Textknotens löschen

Hallo zusammen,

habe mal wieder ein Problem:

was ist an dem folgenden Funktionsaufruf falsch:

document.getElementById("ImgName").lastChild.deleteData(0, 10);

nachdem doch im SELFHTML genau das Gleiche steht

document.getElementsByTagName("p")[0].firstChild.deleteData(0, AnzahlZeichen);

nur dass ich in diesem Fall getElementById() verwende, was mir auch das
richtige Objekt liefert (Abfrage in der Error-Konsole von Webinfo/Safari 4.03):

document.getElementById("ImgName").lastChild
<b>​picture_000.jpg​</b>

Ich bekomme folgenden Fehler gemeldet:
TypeError: Result of expression 'document.getElementById("ImgName").lastChild.deleteData' [undefined] is not a function.

  1. Liebe Gina,

    document.getElementById("ImgName").lastChild
    <b>​picture_000.jpg​</b>

    lese ich das richtig? Mit "ImgName" erhälst Du ein Element, das als letzten Kindknoten ein <b>-Element hat? Dann ist klar, dass Du deleteData() nicht anwenden kannst, da es sich eben um keinen Textknoten, sondern ein <b>-Element handelt.

    Lass Dir mal zur Kontrolle auch den [ref:self812;javascript/objekte/node.htm#node_type@title=nodeType] ausgeben. Hat <meinKnoten>.nodeType den Wert 3, dann hast Du wirklich einen Textknoten. Ansosten brauchst Du von diesem Knoten wiederum den passenden Kindknoten, um endlich einen Textknoten zu haben.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Liebe Gina,

      document.getElementById("ImgName").lastChild
      <b>​picture_000.jpg​</b>

      ...

      Lass Dir mal zur Kontrolle auch den [ref:self812;javascript/objekte/node.htm#node_type@title=nodeType] ausgeben. Hat <meinKnoten>.nodeType den Wert 3, dann hast Du wirklich einen Textknoten. Ansosten brauchst Du von diesem Knoten wiederum den passenden Kindknoten, um endlich einen Textknoten zu haben.

      Liebe Grüße,

      Felix Riesterer.

      Felix, danke für den Hinweis. Es handelt sich natürlich um einen Element-
      Knoten (nodeType=1).

      Das mit dem <b>-Elemt ist mir eigentlich auch schon sauer aufgestossen. Es
      befindet sich innerhelb eines <td>-Elements, und ich dachte eigentlich, mit
      lastChild bekomme ich den innersten Knoten. Wie bekomme ich den nun wirklich?

      Danke u. Gruss
      Gina

      1. Felix, danke für den Hinweis. Es handelt sich natürlich um einen Element-
        Knoten (nodeType=1).

        Das mit dem <b>-Elemt ist mir eigentlich auch schon sauer aufgestossen. Es
        befindet sich innerhelb eines <td>-Elements, und ich dachte eigentlich, mit
        lastChild bekomme ich den innersten Knoten. Wie bekomme ich den nun wirklich?

        Danke u. Gruss
        Gina

        Nach etwas Überlegen ists mir glaub ich klargeworden. Muss zuerst überprüfen,
        ob der gefundene Knoten Childknoten hat (hasChildNodes())
        und mir dann diesen mit nextSibling holen. Richtig?

        Gruss Gina

        1. Liebe Gina,

          den innersten Knoten. Wie bekomme ich den nun wirklich?

          überprüfen, ob der gefundene Knoten Childknoten hat (hasChildNodes())
          und mir dann diesen mit nextSibling holen. Richtig?

          nein. Der Kindknoten eines Kindknotens ist wohl der Kindeskindknoten. Was sich geschrieben schon so doppeltgemoppelt liest, sieht in JavaScript ebenso aus.

          <p id="meinp">Hat wer <strong>"Unfug"</strong> gesagt?</p>

          var meinPElement = document.getElementById("meinp");  
          alert("erster Kindknoten: " + meinp.firstChild); // sollte der Textknoten mit "Hat wer " sein  
          alert("zweiter Kindknoten: " + meinp.firstChild.nextSibling); // sollte das <strong>-Element sein  
          alert("Textknoten im strong-Element: " + meinp.firstChild.nextSibling.firstChild);
          

          Hoffe, das hilft etwas mit dem Verständnis.

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Liebe Gina,

            ...

            <p id="meinp">Hat wer <strong>"Unfug"</strong> gesagt?</p>

            var meinPElement = document.getElementById("meinp");

            alert("erster Kindknoten: " + meinp.firstChild); // sollte der Textknoten mit "Hat wer " sein
            alert("zweiter Kindknoten: " + meinp.firstChild.nextSibling); // sollte das <strong>-Element sein
            alert("Textknoten im strong-Element: " + meinp.firstChild.nextSibling.firstChild);

            
            >   
            > Hoffe, das hilft etwas mit dem Verständnis.  
            >   
            > Liebe Grüße,  
            >   
            > Felix Riesterer.  
              
            Hallo Felix,  
              
            Danke Dir vielmals für die Nachhilfe. Habe heute nacht schon festgestellt,  
            dass ich mit dem nextSibling auf dem Holzweg bin. Da muss ich wohl nochmals  
            Hausaufgaben machen :-)  
              
            Hast mir auf jeden Fall geholfen,  
              
            Gruss  
            Gina
            
          2. Hallo Felix,

            den innersten Knoten. Wie bekomme ich den nun wirklich?

            überprüfen, ob der gefundene Knoten Childknoten hat (hasChildNodes())
            und mir dann diesen mit nextSibling holen. Richtig?

            nein. Der Kindknoten eines Kindknotens ist wohl der Kindeskindknoten.

            Das schon, aber doch nicht zwangsläufig der innerste Knoten, den Gina sucht.

            Wenn in deinem Beispiel einmal statt

            <p id="meinp">Hat wer <strong>"Unfug"</strong> gesagt?</p>

            so etwas dasteht:
            <p id="meinp">Hat wer <strong><i>"Unfug"</i></strong> gesagt?</p>

            dann greift dein Vorschlag mit dem KindesKindknoten schon nicht mehr.

            Gina hat schon recht mit hasChildNodes(). Wenn man in einer Scheife solange zum Kindknoten wechselt, bis keiner mehr existiert, ist man auf der sicheren Seite und hat in jedem Fall den innersten Knoten.

            Gruß, Don P

            1. Lieber Don,

              Wenn in deinem Beispiel einmal statt

              <p id="meinp">Hat wer <strong>"Unfug"</strong> gesagt?</p>
              so etwas dasteht:
              <p id="meinp">Hat wer <strong><i>"Unfug"</i></strong> gesagt?</p>

              dann greift dein Vorschlag mit dem KindesKindknoten schon nicht mehr.

              Gina hat schon recht mit hasChildNodes(). Wenn man in einer Scheife solange zum Kindknoten wechselt, bis keiner mehr existiert, ist man auf der sicheren Seite und hat in jedem Fall den innersten Knoten.

              das ist alles völlig richtig. Mir war es in erster Linie wichtig, dass Gina die Zusammenhänge besser verstehen lernt, um ihre ungeschickte Verwendung von nextSibling zu erkennen. Und das hat sie auch.

              Dass eine gründliche und variable Iteration (z.B. über eine while-Schleife mit hasChildNodes()) die einzig sinnvolle Lösung ist, um an einen "innersten Knoten" zu gelangen, ist ein völlig richtiger Einwand.

              Liebe Grüße,

              Felix Riesterer.

              --
              ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
            2. Hallo Felix,

              den innersten Knoten. Wie bekomme ich den nun wirklich?

              ...

              Gina hat schon recht mit hasChildNodes(). Wenn man in einer Scheife solange zum Kindknoten wechselt, bis keiner mehr existiert, ist man auf der sicheren Seite und hat in jedem Fall den innersten Knoten.

              Gruß, Don P

              Hallo Don P

              vielen Dank auch für Deinen Input. ich hab es mittlerweile hinbekommen, den
              Textknoten rauszufischen. Nur eben, nextSibling war verkehrt, musste
              stattdessen eben wieder nach dem ChildNode fischen.

              Habe jetzt ein anderes Problem:

              Die Sache mit dem deleteData() habe ich eigentlich nur testweise versucht.
              Das eigentliche Ziel ist es, den Text dieses Textknotens auszutauschen.

              Die Anweisung myBElement.firstchild=Unterschrift;wird zwar tadellos
              akzeptiert, liefert als Returnwert, den neuent Text (Unterschrift), aber der
              Textknoten an sich ist danach unverändert. Muss ich den Text wirklich mit
              deleteData(), insertData() bzw. replaceData() in den Knoten reinwurschteln?

              Danke u. Gruss
              Gina

              1. Liebe Gina,

                Die Anweisung myBElement.firstchild=Unterschrift;wird zwar tadellos
                akzeptiert, liefert als Returnwert, den neuent Text (Unterschrift), aber der
                Textknoten an sich ist danach unverändert. Muss ich den Text wirklich mit
                deleteData(), insertData() bzw. replaceData() in den Knoten reinwurschteln?

                Du suchst node.[ref:self812;javascript/objekte/node.htm#replace_child@title=replaceChild()], stimmt's?

                Liebe Grüße,

                Felix Riesterer.

                --
                ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
                1. Liebe Gina,

                  Die Anweisung myBElement.firstchild=Unterschrift;wird zwar tadellos
                  akzeptiert, liefert als Returnwert, den neuent Text (Unterschrift), aber der
                  Textknoten an sich ist danach unverändert. Muss ich den Text wirklich mit
                  deleteData(), insertData() bzw. replaceData() in den Knoten reinwurschteln?

                  Du suchst node.[ref:self812;javascript/objekte/node.htm#replace_child@title=replaceChild()], stimmt's?

                  Liebe Grüße,

                  Felix Riesterer.

                  Hi Felix,

                  Ja, replaceChild() wäre auch eine Methode. Danke. Aber ich glaube, auch ChrisB hat mir den richtigen Tip gegeben mit der .data Eigenschaft, Danke ChrisB, genau an dem Punkt war ich wohl vernagelt.

                  Dank Eurer Hilfe komme ich an der Stelle jetzt wohl zielführend weiter.

                  Liebe Grüsse
                  Gina

                  PS: @ ChrisB
                  Sorry, das mit den Umbrüchen wird nicht mehr passieren. Dachte es sähe besser aus so.

              2. Hi,

                falls du die Umbrüche in deinem Fliesstext absichtlich machst, möchte ich dich bitten, dies zu unterlassen.
                Es ist vor allem beim partiellen Zitieren äusserst lästig.

                Die Anweisung
                myBElement.firstchild=Unterschrift;
                wird zwar tadellos akzeptiert, liefert als Returnwert, den neuent Text (Unterschrift), aber der Textknoten an sich ist danach unverändert.

                Natürlich, schliesslich hast du myBElement damit lediglich eine neue Eigenschaft verpasst, für die sich aber niemand interessieren muss.

                firstchild != firstChild

                (Und wenn du wirklich firstChild angesprochen hättest, dann hättest du einen Laufzeitfehler bekommen müssen, weil du DOM-Elemente nicht einfach mit Strings „überschreiben” kannst.)

                Muss ich den Text wirklich mit deleteData(), insertData() bzw. replaceData() in den Knoten reinwurschteln?

                Die data-Eigenschaft eines Textknotens hilft dir hier weiter.

                MfG ChrisB

                --
                “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
                1. Hallo,

                  Die data-Eigenschaft eines Textknotens hilft dir hier weiter.

                  Oder die http://de.selfhtml.org/javascript/objekte/all.htm#inner_html@title=.innerHTML-Eigenschaft des Elternknotens?
                  *Muss* man die im IE eigentlich unbedingt über das all-Objekt ansprechen?

                  Gruß, Don P

                  1. Hi,

                    Die data-Eigenschaft eines Textknotens hilft dir hier weiter.

                    Oder die http://de.selfhtml.org/javascript/objekte/all.htm#inner_html@title=.innerHTML-Eigenschaft des Elternknotens?

                    Ggf. auch - kommt drauf an, was genau man erreichen will.

                    Wenn der parentNode mehr als nur den auszutauschenden Textknoten enthält, dann muss man da schon wieder zu Suchen-Ersetzen greifen, um den "Rest" zu erhalten; einfach die data-Eigenschaft des Textknotens zu überschreiben, kann da simpler (und weniger fehleranfällig) sein.

                    *Muss* man die im IE eigentlich unbedingt über das all-Objekt ansprechen?

                    Nein, ganz und gar nicht.
                    Das ist eine Eigenschaft, die (fast) alle Elemente haben - und wie man sich die Referenz auf das Element besorgt (document.all ist ja nur ein Weg, um genau das zu tun), ist natürlich ganz egal.

                    (Womit man im IE allerdings aufpassen muss ist, dass es da eine ganze Reihe Elemente gibt, für die innerHTML als read-only definiert ist.)

                    MfG ChrisB

                    --
                    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]