Events im Firefox
Fabian
- javascript
0 M.1 1UnitedPower0 Fabian0 Der Martin0 1UnitedPower0 Fabian0 Der Martin0 Fabian
0 1UnitedPower
Hallo,
ich habe da ein paar Schwierigkeiten mit den Events im Firefox...
Und zwar sieht es folgendermaßen aus:
<input type="text" onKeyUp="checkEnter();">
function checkEnter(evt)
{
if (!evt)
evt = window.event;
if (evt.keyCode == 13)
{
alert('Enter');
return false;
}
}
So, mein lieber Internet Explorer macht da keine Probleme mit..
Firefox hingegen bleibt davon unbeeindruckt und macht gar nix.
Wenn ich dann aber in die Konsole vom Firefox schaue steht da folgendes:
"TypeError: evt is undefined"
Was kann ich da tun?
Fabian
Mahlzeit,
"TypeError: evt is undefined"
Was kann ich da tun?
Wenn die Funktion einen Parameter erwartet, du aber keinen angibst, passiert sowas ;)
Wenn die Funktion einen Parameter erwartet, du aber keinen angibst, passiert sowas ;)
Aber solche Event-Funktionen werden doch überlicherweise so geschrieben oder? http://de.selfhtml.org/javascript/objekte/event.htm@title=(Selfhtml)
Wenn nicht so wie sonst?
Fabian
Mahlzeit,
Aber solche Event-Funktionen werden doch überlicherweise so geschrieben oder? http://de.selfhtml.org/javascript/objekte/event.htm@title=(Selfhtml)
Dieser Artikel ist gefühlte 200 Jahre alt.
Wenn nicht so wie sonst?
Entweder übergibst du beim Aufruf einen Parameter oder du änderst deine Funktion so, dass sie keinen erwartet.
Dieser Artikel ist gefühlte 200 Jahre alt.
Entweder übergibst du beim Aufruf einen Parameter oder du änderst deine Funktion so, dass sie keinen erwartet.
Bekäme ich bitte ein Beispiel wie das mit solchen Funktionen 'heute' aussieht?
(habe einfach mal evt als Parameter weggelassen und eine Variable var evt = window.event; hingeschrieben ... war wohl keine Lösung - jetzt fliegen mir die 'TypeError: window.event is undefined' nur so um die Ohren)
Fabian
Meine Herren!
<input type="text" onKeyUp="checkEnter();">
Der EventHandler (checkEnter) wird hier ohne Parameter aufgerufen. Ich würde den EventHandler auch gar nicht im HTML registrieren, sondern mit JavaScript selbst. Das entspricht eher einer guten Trennung von Inhalt und Verhalten.
HTML
<input id="meinInput">
JavaScript
var inputElement = document.getElementById('meinInput');
inputElement.onkeyup = checkEnter;
// Oder noch schöner
inputElement.addEventListener('keyup', checkEnter );
Wie du siehst, wird die Funktion checkEnter im Code gar nicht aufgerufen. Das macht der Browser aber automatisch, wenn das Event ausgelöst wird und wenn er das macht ruft er die Funtkion mit dem Ereignis-Objekt als Parameter auf. Unter der Haube passiert also sinngemäß irgendwo sowas: checkEnter( keyUpEvent );
Im übrigen solltest du zweimal darüber nachdenken, ob du Standard-Funktionalität von Formular-Feldern anrühren möchtest. Viele Nutzer (mich eingeschlossen) reagieren darauf allergisch – in einigen Fällen ist aber sinnvoll. Du solltest dir die Frage stellen, was der Nutzer erwarten würde, wenn er die Enter-Taste drückt. In den meisten Fällen erwartet er wohl, dass das Formular abgeschickt wird.
var inputElement = document.getElementById('meinInput');
inputElement.addEventListener('keyup', checkEnter );
Also.. jetzt check ich was nicht.
Habe meinen Code jetzt umgestaltet und das Event onKeyUp mit addEventListener in's Javascript geschrieben. Jetzt funktioniert das Event sogar.. (und zwar mit derselben Funktion die M. und die Firefox Konsole bemängelt haben (Die Konsole schweigt jetzt...)):
~~~javascript
function checkEnter(evt)
{
if (!evt)
evt = window.event;
if (evt.keyCode == 13)
{
alert('Enter');
return false;
}
}
Zum Schluss möchte ich noch einmal auch diese Funktion eingehen. M. hat den Selfhtml Artikel ja beinahe als 'mittelalterlich' beschrieben. Also ich kenne nur diesen Weg mit einem Parameter der nicht gesetzt wird aber dann durch if (!evt) dem window.event zugewiesen wird. (Frage nebenbei: wieso nicht einfach den Parameter und if (!evt) ~~ weglassen und einfach if (window.event.~~ schreiben?)
Wie sähe denn so eine Funktion nach M.'s Beschreibung aus?
"Entweder übergibst du beim Aufruf einen Parameter oder du änderst deine Funktion so, dass sie keinen erwartet."
Fabian
Hallo,
Habe meinen Code jetzt umgestaltet und das Event onKeyUp mit addEventListener in's Javascript geschrieben.
'keyup', bitte. In Kleinbuchstaben und ohne 'on'. Im Code steht's ja auch richtig.
Jetzt funktioniert das Event sogar.. (und zwar mit derselben Funktion die M. und die Firefox Konsole bemängelt haben (Die Konsole schweigt jetzt...)):
Was ja nach der Erklärung von 1UP auch logisch und nachvollziehbar ist, oder nicht?
function checkEnter(evt)
{
if (!evt)
evt = window.event;
if (evt.keyCode == 13)
{
alert('Enter');
return false;
}
}
>
> Zum Schluss möchte ich noch einmal auch diese Funktion eingehen. M. hat den Selfhtml Artikel ja beinahe als 'mittelalterlich' beschrieben. Also ich kenne nur diesen Weg mit einem Parameter der nicht gesetzt wird aber dann durch if (!evt) dem window.event zugewiesen wird. (Frage nebenbei: wieso nicht einfach den Parameter und if (!evt) ~~ weglassen und einfach if (window.event.~~ schreiben?)
Weil window.event nur in alten IEs existiert, die hier eine "Exotenlösung" realisiert haben: Alte IEs haben das Event als globales Objekt an window gebunden, während es die anderen als Parameter übergeben.
Ciao,
Martin
--
F: Wer ist der Herrscher über Wasser, Wind und Wellen?
A: Der Friseur.
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
Meine Herren!
var inputElement = document.getElementById('meinInput');
inputElement.addEventListener('keyup', checkEnter );
>
> Also.. jetzt check ich was nicht.
> Habe meinen Code jetzt umgestaltet und das Event onKeyUp mit addEventListener in's Javascript geschrieben. Jetzt funktioniert das Event sogar.
Ja, weil die Funkion auf diese Weise vom Browser automatisch mit einem Parameter aufgerufen wird. Das passiert alles vom Programmier versteckt. Man sagt dem Browser nur welche Funktion er aufrufen soll (addEventListener), den eigentlichen Funktionsaufruf macht dann der Browser. Und der ruft die Funktion dann \_mit\_ Parameter auf.
> Also ich kenne nur diesen Weg mit einem Parameter der nicht gesetzt wird aber dann durch if (!evt) dem window.event zugewiesen wird.
Das `if (!evt) evt = window.event;`{:.language-javascript} ist Hack, den alte InternetExplorer gebraucht haben. Bei InternetExplorern war es nämlich so, dass das Event nicht als Parameter übermittelt wurde, stattdessen wurde eine globale Variable `event`{:.language-javascript} benutzt. In JavaScript können sind globale Variablen das gleiche wie Eigenschaften des window-Objekts. Deswegen kann man immer, wenn man eine globale Variable benutzt, statt `meineGlobaleVariable`{:.language-javascript} auch `window.meineGlobaleVariable`{:.language-javascript} schreiben.
> (Frage nebenbei: wieso nicht einfach den Parameter und if (!evt) ~~ weglassen und einfach if (window.event.~~ schreiben?)
Weil der Weg über die globale Variable veraltet ist. Ein Funktionsparameter ist die neuere und saubere Variante.
--
“All right, then, I'll go to hell.” – Huck Finn
Erstmal ein großes Dankeschön! Das hat schon einige Fragen beantwortet.
Um sicherzugehen dass ich es jetzt kapiert habe eine allerletzte Frage:
Weil der Weg über die globale Variable veraltet ist. Ein Funktionsparameter ist die neuere und saubere Variante.
Sähe die "neuere und saubere Variante" so aus? :
window.onload = function() {
document.getElementById('meinInput').addEventListener('click', meinInputEvent);
};
function meinInputEvent(e)
{
// Für Leute die einen veralteten Internet Explorer haben
e = e || window.event;
// Eigentliche Funktion
if (e.keyCode == 13)
{
alert('Du hast auf Enter geklickt');
return false;
}
}
Ich hoffe das ist jetzt die "moderne Variante" sonst bitte korrigieren.
Fabian
Hallo,
window.onload = function() {
document.getElementById('meinInput').addEventListener('click', meinInputEvent);
};function meinInputEvent(e)
{
// Für Leute die einen veralteten Internet Explorer haben
e = e || window.event;// Eigentliche Funktion
if (e.keyCode == 13)
{
alert('Du hast auf Enter geklickt');
return false;
}
}
das ist ganz bestimmt "sauber": Keine Vermischung von HTML und Javascript, keine globalen Variablen (bis auf den Zugriff auf window.event, der für alte IEs nötig ist). Nur ein logischer Fehler fällt auf: Du registrierst deinen Eventhandler für das click-Ereignis - ein click-Event hat aber keine (sinnvolle) Informationen in keyCode.
Vermutlich meintest du 'keyup' oder 'keypress' als auslösendes Event.
Und noch etwas: Der onload-Handler des window-Objekts löst erst aus, wenn auch alle untergeordneten Ressourcen (Bilder, Scripts, Stylesheets) fertig geladen sind. Das kann unter Umständen eine Weile dauern. In der Zeit ist deine Eventhandler-Funktion dann noch nicht "scharf".
Der pragmatische Kompromiss ist, die Initialisierung der Eventhandler nicht erst 'onload' zu machen, sondern diese eine Script-Zeile "einfach so" am Ende des Dokuments, also vor dem schließenden body-Tag zu notieren.
So long,
Martin
--
Ein Patriot ist jemand, der bereit ist, sein Land gegen seine Regierung zu verteidigen.
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
Nur ein logischer Fehler fällt auf: Du registrierst deinen Eventhandler für das click-Ereignis - ein click-Event hat aber keine (sinnvolle) Informationen in keyCode.
Vermutlich meintest du 'keyup' oder 'keypress' als auslösendes Event.
Ups, 'keyup' gedacht aber 'click' geschrieben..
Der pragmatische Kompromiss ist, die Initialisierung der Eventhandler nicht erst 'onload' zu machen, sondern diese eine Script-Zeile "einfach so" am Ende des Dokuments, also vor dem schließenden body-Tag zu notieren.
Alles klar. Vielen Dank für den Tipp.
Fabian
Meine Herren!
e = e || window.event
;
Was diesen Hack angeht, hab ich mich ein wenig zu kurz gefasst. Dieser Hack wurde von dem Event-System benötigt, wie es in InternetExplorern 4-6 implementiert war. Da gab es auch input.addEventListener()
noch gar nicht. Da gab es nur input.onkeyup
. Wenn du dich also für das neue (Standard)Event-System entscheidest, kannst du dir diesen Hack auch sparen, denn dann entfällt die Unterstützung für die (Ur)Zeitgenossen IE4-6 sowieso. Mehr zum Thema, kann man in JavaScript The Defenitive Guide nachlesen.
Und du solltest dich aus stilistischen Gründen für EIN Event-System entscheiden. Das hilft deinen Code in diesem Punkt konsistent zu halten.
du könntest statt dem hier:
window.onload = function() {
document.getElementById('meinInput').addEventListener('keyup', meinInputEvent);
};
das hier benutzen:
window.addEventListener('load', function() {
document.getElementById('meinInput').addEventListener('keyup', meinInputEvent);
});
Oder, in Hinblick auf Martins Kritik, auch das hier:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('meinInput').addEventListener('click', meinInputEvent);
});
Das DOMContentLoaded-Ereignis wird ausgelöst, nachdem der ganze HTML-Quelltext geparst wurde. Im Gegensatz zu dem load-Ereignis wird nicht zusätzlich darauf gewartetet, dass alle Bilder und andere Resourcen vollständig runtergeladen sind.
Das Skript am Ende des Dokuments zu platzieren macht aber auch aus anderen, praktischen Gründen Sinn: Das Rendering der Seite wird nämlich unterbrochen, wenn der Browser beim Parsen über einen JavaScript-Quelltext stößt. Wenn man den Browser bei diesem Vorgang so spät wie möglich unterbricht, bekommt der Nutzer schon früher etwas zu sehen.