Dynamisch erzeugtes onClick-Attribut funktioniert nicht im IE
Colin Finck
- javascript
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
Hell-O!
Gibt es da eine Lösung für den IE?
Ja, sprich die Eigenschaft des Attributes direkt an:
elem.onclick = test;
Siechfred
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
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
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
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:
Mathias
Hi,
eval("elem.onclick = function() {test('" + arg1 + "');}");
Kürzer: elem.onclick = function() {test(arg1);}
Gruß, Cybaer
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.