Fabulit: Anfängerfrage: Verweis auf DOM-Objekt speichern

Hallo wehrte Forumsgemeinde,

ich möchte einen Verweis auf ein DOM-Objekt speichern, ohne eine Id zu verwenden. Gegeben ist ein Input-Element. Dieses Element besitzt einen onclick-Eventhandler. Der zugehörige Funktionsaufruf übergibt das geklickte Element per this. Und nun möchte ich dieses this als Eigenschaft eines Javascript-Objekts speichern. Allerdings speichere ich augenscheinlich keinen Verweis auf das DOM-Objekt, sondern erzeuge ein neues Objekt.

Ich denke, der nachfolgende Beispiel-Code verdeutlicht mein Vorhaben. Meine Frage ist nun, ob ich meinen Ansatz ohne Id verwirklichen kann?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
<html>  
  <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
    <title>Referenz auf Dom-Objekt speichern</title>  
  </head>  
  <body>  
    <p>  
      <input type="text" value="vorbelegt" onclick="meinObjekt.erstelleKnopf(this);" id="check1">  
      <input type="text" value="vorbelegt" onclick="meinObjekt.erstelleKnopf(this);" id="check2">  
    </p>  
    <script type="text/javascript">  
      [code lang=javascript]var meinObjekt = {  
        erstelleKnopf : function (zielInput) {  
          this.zielInput = zielInput; //dies ist die kritische Stelle  
          var button = '<input type="button" onclick="meinObjekt.setzeWert(this);" value="Wert setzen">';  
          document.getElementsByTagName("P")[0].innerHTML += button;  
        },  
        setzeWert : function (el) {  
          meinObjekt.zielInput = "Skriptwert";  
          el.parentNode.removeChild(el);  
        }  
      };

</script>
  </body>
</html>[/code]

  1. meinObjekt.zielInput = "Skriptwert";

    wurde korrigiert auf

    meinObjekt.zielInput.value = "Skriptwert";

  2. Hi,

    ich möchte einen Verweis auf ein DOM-Objekt speichern, ohne eine Id zu verwenden. Gegeben ist ein Input-Element. Dieses Element besitzt einen onclick-Eventhandler. Der zugehörige Funktionsaufruf übergibt das geklickte Element per this. Und nun möchte ich dieses this als Eigenschaft eines Javascript-Objekts speichern. Allerdings speichere ich augenscheinlich keinen Verweis auf das DOM-Objekt, sondern erzeuge ein neues Objekt.

    nein, Du vernichtest das bestehende Objekt ...

    document.getElementsByTagName("P")[0].innerHTML += button;

    ... genau hier. Der Inhalt wird durch Zuweisung von innerHTML neu erzeugt; damit ist alles, was vorher drin war, nicht mehr existent.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. ach so, ja klar. ich sag ja; Anfängerfrage! Vielen Dank

  3. var button = '<input type="button" onclick="meinObjekt.setzeWert(this);" value="Wert setzen">';
              document.getElementsByTagName("P")[0].innerHTML += button;

    Wenn du innerHTML += '...' schreibst, wird innerHTML ausgelesen, indem das DOM serialisiert wird. Dann wird dem zurückgegebenen String ein weiterer String angehängt und innerHTML zugewiesen. Dabei wird der String wieder geparst, es werden neue DOM-Knoten erzeugt und der Elementinhalt wird durch diese Knoten ersetzt.

    Wenn du jetzt vorher einen Verweis auf ein Kindelement hattest, so führt er nun ins Leere, weil das Element durch ein neues (wenn auch gleiches) ersetzt wurde. Sämtliche daran gespeicherte Informationen wie mit JavaScript registrierte Event-Handler gehen auch verloren.

    Das will man eigentlich so gut wie nie, daher ist innerHTML += weitgehend untauglich. Besser ist, du verwendest die DOM-Methoden wie http://de.selfhtml.org/javascript/objekte/node.htm#append_child@title=appendChild oder, wenn du unbedingt mit Strings arbeiten willst, insertAdjacentHTML('beforeEnd', 'HTML-Code').

    Im Sinne der Trennung von HTML und JavaScript sollte man ohnehin mit Event-Handling ohne eingebettetes JavaScript arbeiten. Dazu ist createElement/appendChild nützlicher.

    var button = document.createElement('input');  
    button.type = 'button';  
    button.value = 'Wert setzen';  
    button.onclick = meinObjekt.setzeWert;  
    document.getElementsByTagName("P")[0].appendChild(button);
    

    In setzeWert kannst du mit this auf den Button (das Zielelement) zugreifen. Als ersten Parameter bekommt die Handler-Funktion dann das Event-Objekt.

    setzeWert : function (event) {  
       meinObjekt.zielInput.value = "Skriptwert";  
       this.parentNode.removeChild(this);  
    }
    

    So ähnlich kannst du natürlich auch beim Registrieren der Event-Handler für die <input type="text"> vorgehen.

    Mathias

    1. Vielen Dank für deine Ausführungen.

      ... daher ist innerHTML += weitgehend untauglich.

      Das werde ich mir merken. Ich hatte tatsächlich nicht weiter drüber nachgedacht, dass innerHTML eine Neu-Konstruktion des DOMs zur Folge hat.

      appendChild habe ich aus "Faulheit" umgangen, bzw. wollte ich den Beispielcode kurz halten und daher mit einem String arbeiten. Ich werde mir insertAdjacentHTML('beforeEnd', 'HTML-Code') mal genauer anschauen und in der Praxis mit appendChild arbeiten.

      In setzeWert kannst du mit this auf den Button (das Zielelement) zugreifen.

      Das ist ein guter Tipp. Allerdings auch der Grenzbereich meines Javascript-Scope-Verständnisses. In meiner Test-Umgebung habe ich den Ansatz nicht eingebunden bekommen. Ich habe die Funktion setzeWert ohne Übergabeparameter aufgerufen und dann event 'abgefangen'. Diese Vorgehensweise ist mir auch schon woanders untergekommen. Allerdings verweist this nach wie vor auf meinObjekt. Ich werde mir mal deinen Artikel (nicht zum ersten Mal) zu Gemüte führen und vielleicht verstehe ich jetzt wieder etwas mehr. Aber noch hat eine "Weisheit" für mich Bestand; verwende kein this, wenn es nicht unbedingt nötig ist. :-)

      Danke und schönen Sonntag erst einmal.

      1. In setzeWert kannst du mit this auf den Button (das Zielelement) zugreifen.

        Habs hinbekommen. Man sollte bei onclick die Funktion registrieren und nicht deren Ergebnis. :-)