Colin Finck: Dynamisch erzeugtes onClick-Attribut funktioniert nicht im IE

Hallo,

Ich habe hier folgenden JavaScript-Code, um einen Button inkl. onClick-Attribut dynamisch zu erzeugen. Beim Klick auf den Button soll dann eine Meldung erscheinen.

---------------------------------------------------------
function createbtn()
{
  var elem = document.createElement("input");
  var onclick = document.createAttribute("onclick");

elem.type = "button";
  elem.value = "Test";
  onclick.nodeValue = "test()";
  elem.setAttributeNode(onclick);

document.getElementsByTagName("body")[0].appendChild(elem);
}

function test()
{
  alert("Test");
}
---------------------------------------------------------

Dieser Code funktioniert problemlos unter Firefox, Opera und Swift, aber nicht im Internet Explorer. Ich habe sowohl IE6 als auch IE7 getestet und bei beiden passiert nach dem Klick auf den Button nichts.
Ich habe ebenfalls bereits versucht, aus dem "test()" ein "javascript:test()" zu machen, dies hilft aber auch nicht.

Gibt es da eine Lösung für den IE?

Vielen Dank im Voraus,

Colin Finck

--
Homepage: http://www.ColinFinck.de
Programme, PE Builder-Stuff (Plugins und Linkliste), Add-Ins und Sonstiges
  1. Hell-O!

    Gibt es da eine Lösung für den IE?

    Ja, sprich die Eigenschaft des Attributes direkt an:

    elem.onclick = test;

    Siechfred

    --
    Ich bin strenggenommen auch nur interessierter Laie. (molily)
    Siechfreds Tagebuch || Steuerfreie Geburtsbeihilfen? || RT 221 Erfurt-Altstadt i.V.
    1. Ok, so funktioniert es im IE.

      Allerdings kann ich dann der Funktion keine Argumente übergeben. Was mach ich z.B., wenn die test()-Funktion folgendermaßen aussieht?

      ------------------------------------
      function test(x)
      {
        alert(x);
      }
      ------------------------------------

      Bei den anderen Browsern könnte ich dann einfach

      onclick.nodeValue = "test('Hallo')";

      benutzen.

      Gibt es dafür auch eine Lösung für den IE?

      Beste Grüße,

      Colin Finck

      --
      Homepage: http://www.ColinFinck.de
      Programme, PE Builder-Stuff (Plugins und Linkliste), Add-Ins und Sonstiges
      1. Hi,

        Allerdings kann ich dann der Funktion keine Argumente übergeben.

        Du kannst eine anonyme Funktion verwenden, die selbst keine Argumente benötigt, aber die schönsten Aufrufe mit dutzenden Argumenten beliebiger Komplexität durchführt.

        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. Danke für die Antworten. Ich habe es jetzt mit einer anonymen Funktion gemacht.

          Folgendermaßen lässt sich durch diese anonyme Funktion jede Funktion mit Argumenten aufrufen:

          ----------------------------------------

            
          var arg1 = "Hallo";  
          eval("elem.onclick = function() {test('" + arg1 + "');}");  
          
          ~~~----------------------------------------  
            
          Sieht zwar nicht so schön aus, aber funktioniert unter IE, Firefox und Opera perfekt :-)  
            
          Beste Grüße,  
            
          Colin Finck  
          
          -- 
          Homepage: <http://www.ColinFinck.de>  
          Programme, PE Builder-Stuff (Plugins und Linkliste), Add-Ins und Sonstiges
          
          1. Hallo,

            var arg1 = "Hallo";

            eval("elem.onclick = function() {test('" + arg1 + "');}");

            
            > Sieht zwar nicht so schön aus, aber funktioniert unter IE, Firefox und Opera perfekt :-)  
              
            Sieht tatsächlich nicht schön aus, so solltest du nicht vorgehen. eval() ist sehr langsam, fehlerträchtig und darüber hinaus schlechter Programmierstil, Code im Code dynamisch zusammenzusetzen.  
              
            eval() ist eigentlich immer unnötig und die schlechtere der möglichen Alternativen, es gibt viele bessere Methoden.  
              
              
            Wenn du unbedingt JavaScript-Code als String notieren willst, kannst du so eine Funktion notieren:  
              
            ~~~javascript
            var handler = new Function("test(" + arg + ")");  
            elem.onclick = handler;
            

            Siehe Defining functions.

            Das hat aber immer noch einige Nachteile, schließlich wird dabei auch so eine Art eval() durchgeführt.

            Eine bessere, vielseitigere und einfachere Methode ist es, die im Handler benötigten Variablen als Eigenschaften am Elementobjekt zu speichern.

            elem.arg1 = "Hallo";  
            elem.onclick = handler;  
              
            function handler () {  
               alert(this.arg1);  
            }
            

            Noch einmal zurück zu deinem eval-Code:

            var arg1 = "Hallo";  
            eval("elem.onclick = function() {test('" + arg1 + "');}");
            

            Bei diesem minimalen Beispiel ist eval() überhaupt nicht nötig. Wenn du folgendes schreibst,

            var arg1 = "Hallo";  
            elem.onclick = function () {  
               alert(arg1);  
            };
            

            wirst du dich wundern, dass arg1 in der Funktion verfügbar ist (auch wenn arg1 keine globale Variable ist). Denn die Funktion wirkt hier als Closure. (Diesen Artikel solltest du dir ohnehin anschauen, siehe auch Möglichkeiten der Datenspeicherung)

            Closures sind die zweite vielseitige Möglichkeit, um Objekte bzw. Variablen in Event-Handler-Funktionen zur Verfügung zu stellen, die dort sonst nicht zur Verfügung stünden.

            Es gibt also zusammengefasst folgende Alternativen:

            • Die Daten als Eigenschaften am Elementobjekt speichern, wo der Event passiert bzw. durch Event-Bubbling vorbeikommt und behandelt wird. Auf diese Daten kann man im Handler einfach über this.eigenschaft zugreifen.
            • Die Daten durch Closures in den Handler-Funktionen verfügbar machen, sofern möglich.
            • Wenn die anderen beiden Methoden nicht zum Ziel führen: Dynamisch Funktionen erzeugen, indem man deren Funktionskörper als String erzeugt und new Function() verwendet.

            Mathias

            --
            »No nations, no borders.«
            SELFHTML Weblog
          2. Hi,

            eval("elem.onclick = function() {test('" + arg1 + "');}");

            Kürzer: elem.onclick = function() {test(arg1);}

            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. Bei den anderen Browsern könnte ich dann einfach

        onclick.nodeValue = "test('Hallo')";

        schon erstaunlich.

        Gibt es dafür auch eine Lösung für den IE?

        und für die anderne Browser:

          
        [object].onclick = function(e)  
        {  
             test('hallo');  
        }  
        
        

        Dir ist aber auch klar, dass du innerhalb der Funktion direkt auf das Objekt zugreifen kannst über this?
        also dass du hier z.b. keine id übergeben musst.

        Struppi.

        --
        Javascript ist toll (Perl auch!)