addEventListener funktioniert nicht wie gedacht

26/09/2015 - 07:25 von Maik Koenig | Report spam
Servus!

Gegeben ist ein recht umfangreiches Dokument mit ca 120 Input-Feldern.
Alle Felder haben neben unterschiedlichen CSS-Klassen auch eine
gemeinsam, damit das hier funktioniert(*1):

var k = document.getElementsByClassName("Foo");
for(var i = 0; i < k.length; i++) {
getID(k[i].id).addEventListener('keyup', Rechnen);
getID(k[i].id).addEventListener('change', Rechnen);
getID(k[i].id).addEventListener('focus', Fokus(k[i].id), true);
getID(k[i].id).addEventListener('blur', Verlassen(k[i].id), true);
};

function Fokus(Feld) {
getID(Feld).style.background = "yellow";
DebugMeldung ('Fokus wurde erkannt im Feld '+Feld);};

function Verlassen(Feld) {
getID(Feld).style.background = "";
DebugMeldung ('Blur wurde erkannt im Feld '+Feld);};

Per onLoad-Event im Body wird die Sammelfunktion aufgerufen, in der u.A.
auch obiger Ausschnitt enthalten ist. Etwas spàter im Code werden alle
Felder aus dem LocalStorage mit Inhalten befüllt (oder, wenn dort nichts
vorhanden, mit Standardwerten).

Das Problem ist jetzt, dass es grundsàtzlich funktioniert: Beim Befüllen
aus dem Speicher feuert jedes Element die DebugMeldung ab.

Aber wenn die Seite fertig geladen im Browser ist (hier: Firefox 40.x.x)
reagieren die Funktionen für focus und blur nicht mehr wàhrend keyup und
change korrekt arbeiten.

Ich scheine da irgendwo einen Denkfehler zu haben aber ich komme ums
Verrecken nicht drauf wo genau. Kann mir jemand eventuell auf die
Sprünge helfen?

*1: getID = function(ID) {return document.getElementById(ID);}

Greetz,
MK
blog.maikkoenig.de // Des Wahnsinns fette Beute.
 

Lesen sie die antworten

#1 Thomas PointedEars Lahn
26/09/2015 - 09:12 | Warnen spam
Maik Koenig wrote:

Gegeben ist ein recht umfangreiches Dokument mit ca 120 Input-Feldern.
Alle Felder haben neben unterschiedlichen CSS-Klassen auch eine
gemeinsam, damit das hier funktioniert(*1):

var k = document.getElementsByClassName("Foo");



“k” ist ein nichtssagender Bezeichner. Verwende “fields” o.à.

Verwende besser kleingeschriebene Klassennamen. Willst Du auch IE < 9 oder
IE 9 im Compatibility Mode unterstützen, musst Du
document.getElementsByClassName() emulieren.

for(var i = 0; i < k.length; i++) {



for (var i = 0, len = k.length; i < len; ++i) {

getID(k[i].id).addEventListener('keyup', Rechnen);
[…]



// jedoch siehe oben; es böte sich dann “field” statt “ki” an.
var ki = k[i];
ki.addEventListener('keyup', Rechnen);

usw.

.addEventListener() musst Du wieder emulieren, wenn Du IE < 9 und IE 9
Compat unterstützen willst.

“Rechnen” sollte “rechnen” usw. bzw. “calc” oder “calculate” usw. sein, denn
es handelt sich nicht um einen Konstruktor, und üblich (weil international
verstàndlich) sind englischsprachige Bezeichner (selbst in de.comp.lang.*).

Globale Funktionen und Variablen sind zu vermeiden. Siehe Module Pattern.

Informier Dich über Event-Bubbling, so dass Du das Hinzufügen von Event-
Listenern zu jedem einzelnen Element einer Elementgruppe vermeiden kannst.

getID(k[i].id).addEventListener('change', Rechnen);
getID(k[i].id).addEventListener('focus', Fokus(k[i].id), true);



Das ruft die Funktion mit dem Namen “Fokus” auf beim Hinzufügen des
Listeners auf, also lange *bevor* der focus-Event eintritt. Die Funktion
hat keinen expliziten Rückgabewert, ihr Rückgabewert ist also der
“undefined”-Wert. Dieser Wert ist für einen Event-Listener unzulàssig;
bestenfalls wird er ignoriert, schlimmstenfalls führt er zu einem
Laufzeitfehler.

Du suchst (bzw. eher nicht, siehe unten):

k[i].addEventListener('focus', function () { Fokus(k[i].id) }, true);

getID(k[i].id).addEventListener('blur', Verlassen(k[i].id), true);



Dito.

};

function Fokus(Feld) {
getID(Feld).style.background = "yellow";



function focus (field)
{
field.style.background = "yellow";

DebugMeldung ('Fokus wurde erkannt im Feld '+Feld);};



Es handelt sich um eine Funktionsdeklaration, das Semikolon am Ende der
Zeile ist daher überflüssig. Verwende JSHint.

[…]
Per onLoad-Event



_load_-Event

[…]
*1: getID = function(ID) {return document.getElementById(ID);}



Das macht Deinen Code nur *noch* langsamer. Wenn Du “getID” nicht
deklarierst (ich sehe hier kein “var”), ausserdem fehlertràchtiger und
inkompatibler.

“ID” sollte wieder “id” sein, denn es handelt sich nicht um eine Konstante.

PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Ähnliche fragen