Kerse: Onclick per JavaScript eine Funktion mit Parametern zuweisen

Hallo.

Ich moechte ein Objekt schreiben das bei seiner Initialisierung dynamisch in einem frei waehlbaren div-Bereich ein paar Bilder einfuegt und dabei allen Bildern die selbe Funktion als onlick-Event zuweist. Die Funktion soll bei jedem Bild aber mit unterschiedlichen Parametern uebergeben werden.

Mein Problem ist, dass ich zwar die Funktion zuweisen kann und auch ein Parameter uebergeben wird, leider ist es aber immer derselbe (der letzte) Parameter.

Folgend ein Beispielcode:

  
<html>  
  
<head>  
  
  <script type="text/javascript">  
  
    function MyObject(divBereich)  
      {  
      this.divBereich = divBereich;  
      this.DoSomething = DoSomething;  
        for (i = 0; i < 5; i++)  
          {  
            var Element = document.createElement("img");  
            Element.id = "bild" + i;  
            Element.src = "bild" + i + ".jpg";  
            Element.style.width = "50px";  
            Element.style.height = "50px";  
            Element.onclick = function(){DoSomething(Element.src);};  
            document.getElementById(this.divBereich).appendChild(Element);  
          }  
      }  
  
    function DoSomething(Variable)  
      {  
        alert(Variable);  
      }  
  
  </script>  
  
</head>  
  
<body>  
  
  <div id="Output"></div>  
  
  <script type="text/javascript">  
    var Object1 = new MyObject("Output");  
  </script>  
  
</body>  
  
</html>  

Das Script sollte dafuer sorgen das bei einem Klick auf eines der Bilder eine Alert-Box erscheint die den Pfad des jeweiligen Bildes ausgibt.
Leider erscheint beim Klick auf jedes der Bilder aber immer der Pfad des letzten Bildes (bild4.jpg).

Was mache ich falsch?

  1. Element.onclick = function(){DoSomething(Element.src);};
    Was mache ich falsch?

      
    Element.onclick = function(){DoSomething(this.src);};  
    
    
    1. »» Element.onclick = function(){DoSomething(Element.src);};
      »» Was mache ich falsch?

      Element.onclick = function(){DoSomething(this.src);};

        
      Super funktioniert wunderbar. Vielen Dank.  
        
      Leider verstehe ich noch nicht ganz warum?  
        
      Auch habe ich nun das Problem, dass wenn ich statt dem Bildpfad den Index "i" uebergeben will wieder das gleiche passiert (es wird immer "5" ausgegeben).  
        
      Irgendeine Idee?
      
      1. wenn ich statt dem Bildpfad den Index "i" uebergeben will wieder das gleiche passiert (es wird immer "5" ausgegeben).

        Falls du den Index wirklich brauchst, kannst du ihn gesondert am img-Elementobjekt speichern:

        Element.i = i;

        In der Handler-Funktion wie gewohnt auslesen über

        this.i

        Mathias

  2. Was mache ich falsch?

    Du verwendest ene Closure in einer Schleife.
    Suche im Forumsarchiv

    Einfache Lösung: Verzicht auf den Zugriff auf die Variable »Element«, die nämlich nach dem Ablauf der Schleife nicht auf das jeweilige, sondern auf das letzte Element verweist.

    Element.onclick = function(){ DoSomething(this.src); };

    Zugriff auf das Zielelement eines Ereignisses

    Mathias

    1. Hi,

      Einfache Lösung: Verzicht auf den Zugriff auf die Variable »Element«, die nämlich nach dem Ablauf der Schleife nicht auf das jeweilige, sondern auf das letzte Element verweist.

      Element.onclick = function(){ DoSomething(this.src); };

      Auch das sieht mir in diesem Falle noch überflüssig aus - this *innerhalb* der Funktion verweist doch hier (beim traditionellen Eventhandling) sowieso auf das Element, auf das geklickt wurde - also kann man this.src auch innerhalb der Funktion abfragen, und muss es gar nicht erst als Parameter übergeben.

      MfG ChrisB

      --
      Light travels faster than sound - that's why most people appear bright until you hear them speak.
      1. this *innerhalb* der Funktion verweist doch hier (beim traditionellen Eventhandling) sowieso auf das Element, auf das geklickt wurde - also kann man this.src auch innerhalb der Funktion abfragen, und muss es gar nicht erst als Parameter übergeben.

        MfG ChrisB

        Habe es gerade mal versucht, aber wenn ich nichts per Element.onclick = function(){DoSomething();}; uebergebe und versuche aus der Funktion DoSomething heraus alert(this.src); aufzurufen bekomme ich leider nur "undefined" zurueck.

        1. Hi,

          Habe es gerade mal versucht, aber wenn ich nichts per Element.onclick = function(){DoSomething();}; uebergebe und versuche aus der Funktion DoSomething heraus alert(this.src); aufzurufen bekomme ich leider nur "undefined" zurueck.

          Element.onclick = DoSomething;

          MfG ChrisB

          --
          Light travels faster than sound - that's why most people appear bright until you hear them speak.
          1. [latex]Mae  govannen![/latex]

            Habe es gerade mal versucht, aber wenn ich nichts per Element.onclick = function(){DoSomething();}; uebergebe und versuche aus der Funktion DoSomething heraus alert(this.src); aufzurufen bekomme ich leider nur "undefined" zurueck.

            Element.onclick = DoSomething;

            Der erste Funktionsparameter von DoSomething enthält dann das Eventobjekt (Nicht im IE), nicht aber das Elementobjekt. Dieses kann man dann indirekt zwar wieder mit <eventobject>.target bzw. <eventobject>.srcElement (IE) ermitteln, aber das ist bei einem _direkt ans Zielelement_ gehängten Event irgendwie überflüssig. Dann kann man auch this.src direkt übergeben.

            BTW: Ich würde nicht this.src an die Funktion übergeben, sondern nur this, damit erspart man sich eine Menge Änderungen, falls man irgendwann mal zusätzliche Eigenschaften des Elements benötigt.

            Cü,

            Kai

            --
            „It's 106 miles to Chicago, we got a full tank of gas, half a pack of cigarettes, it's dark, and we're wearing sunglasses“.
            „Hit it!“
            Selfzeugs
            SelfCode: sh:( fo:| ch:? rl:( br:< n4:( ie:{ mo:| va:) js:| de:> zu:) fl:( ss:| ls:?
            1. Hi,

              Element.onclick = DoSomething;

              Der erste Funktionsparameter von DoSomething enthält dann das Eventobjekt (Nicht im IE), nicht aber das Elementobjekt.

              Ich rede ja auch nicht von Parametern, sondern this innerhalb der Funktion - das referenziert auf Element.

              MfG ChrisB

              --
              Light travels faster than sound - that's why most people appear bright until you hear them speak.
              1. Hi,

                »» > Element.onclick = DoSomething;
                »»
                »» Der erste Funktionsparameter von DoSomething enthält dann das Eventobjekt (Nicht im IE), nicht aber das Elementobjekt.

                Ich rede ja auch nicht von Parametern, sondern this innerhalb der Funktion - das referenziert auf Element.

                MfG ChrisB

                Erst mal vielen Dank fuer die ganze Hilfe. Ich glaube, dass ich das ganze jetzt langsam verstehe.

                Also entweder ich uebergebe mittels Element.onclick = function(){ DoSomething(this); } das Element als Parameter an die Funkiton DoSomething, welche unter "this" dann eben jenes Element referenziert

                oder

                ich weise die Funktion direkt und ohne Parameter in der Form Element.onclick = DoSomething; zu und greife mit der Funktion DoSomething über "this" stattdessen auf das Event-Objekt zu?

                Wie bekomme ich es nun aber hin, dass ich auch auf die Eigenschaften von MyObject (z.B. divBereich)in der Funktion DoSomething zugreifen kann (ohne diese als Parameter zusaetzlich mit zu uebergeben)?

                1. Also entweder ich uebergebe mittels Element.onclick = function(){ DoSomething(this); } das Element als Parameter an die Funkiton DoSomething, welche unter "this" dann eben jenes Element referenziert

                  Richtig. Aber diese Schreibweise ist redundant. Diese zusätzliche Funktion macht nur Sinn, wenn du noch etwas anderes als this übergeben wilst (s.u. meine Antwort auf deine weitere Frage).

                  ich weise die Funktion direkt und ohne Parameter in der Form Element.onclick = DoSomething; zu und greife mit der Funktion DoSomething über "this" stattdessen auf das Event-Objekt zu?

                  Nein, this verweist nie auf das Event-Objekt. Auch in dem Fall würde this auf das Element verweisen. Das tut es immer beim traditionellen Event-Handling.

                  Der Zugriff auf das Event-Objekt funktioniert anders.

                  element.onclick = DoSomething;  
                    
                  function DoSomething (e) {  
                     if (!e) e = window.event;  
                     alert("Event-Objekt: " + e);  
                     alert("Verarbeitendes Element: " + this);  
                  }
                  

                  Wie bekomme ich es nun aber hin, dass ich auch auf die Eigenschaften von MyObject (z.B. divBereich)in der Funktion DoSomething zugreifen kann (ohne diese als Parameter zusaetzlich mit zu uebergeben)?

                  In dem Fall kannst du eine Closure sicher verwenden:

                  function MyObject () {  
                     var instance = this;  
                     ...  
                     function clickHandler () {  
                        /* Closure, schließt instance ein, während this auf das Element zeigt */  
                        DoSomething(instance, this);  
                        /* Wenn du hier noch das Event-Objekt brauchst, müsstest du es ebenfalls übergeben (s.o.) */  
                     }  
                     ...  
                     for (...) {  
                        Element.onclick = clickHandler;  
                     }  
                  }
                  

                  Übrigens solltest du ein Konstruktor nicht MyObject nennen (weil nicht aussagekräftig) und eine Variable nicht Element (weil Element die Konstruktorfunktion für Elemente ist - es ist zwar sicher, die lokal zu überschreiben, aber irgendwann wirst du dich wundern, wenn du mal auf diesen Konstuktor zugreifen willst).

                  Und die Handler-Funktion würde ich auch nicht mit jedem Schleifendurchgang neu erzeugen. Es reicht, sie einmal als lokale Funktion in der Funktion (damit sie die anderen lokalen Variablen als Closude einschließt), aber außerhalb der Schleife zu erzeugen, wie oben demonstriert.

                  Mathias