Klassenattribut in Klassenmethode nicht benutzbar
Mastershrimp
- javascript
0 Mastershrimp0 Struppi
1 Mathias
Heyho!
Ich bastele gerade an einem Script, das nach dem Laden eines Dokuments aufgerufen werden soll und bei jedem Input-Feld das maxlength-Attribut ausliest, dieses dann entfernt und einen onkeydown-Handler einfügt, der eine Methode startet, die die Eingabelänge überprüft.
Nach einem prozeduralen Versuch, der gründlich in die Hose ging, hier nun ein objektorientierter. Allerdigns sind die Attribute maxLength und inputElem in der Methode keydown nicht benutzbar (maxLength ist "-1" und inputElem ist "undefined").
Warum?
function loadInputLengthChecker() {
var inputFields = document.getElementsByTagName("input");
if(inputFields.length > 0) {
for(var i=0; i<inputFields.length; i++) {
var curInputField = Element.extend(inputFields[i]);
new InputLimit(curInputField);
}
}
}
var InputLimit = Class.create( {
initialize: function(element) {
this.inputElem = element;
this.maxLength = element.getAttribute("maxlength");
if(this.maxLength!=null) {
element.removeAttribute("maxlength");
element.onkeydown = this.keydown;
}
//alert("Ergebnis von initialize: inputElem=" + this.inputElem + ", maxLength=" + this.maxLength);
},
keydown: function() {
if(this.maxLength > 0) {
if(this.inputElem.value.length > this.maxLength) {
alert("In dieses Eingabefeld dürfen nur " + this.maxLength + " Zeichen eingegeben werden!");
this.inputElem.value = this.inputElem.value.substr(0, this.maxLength);
}
}
else
alert("inputElem: " + this.inputElem + ", maxLength: " + this.maxLength);
}
});
Das ganze wird wie gesagt mit <body onload="loadInputLengthChecker()"> gestartet.
Gruß
Mastershrimp
Ups, ganz vergessen dass ich die Prototype-Bibliothek zusätzlich einsetze ;)
Also nicht über die eine oder andere fremde Methode wundern ;)
element.onkeydown = this.keydown;
Das geht nicht. Du musst hier einen Umweg gehen.
var self = this;
element.onkeydown = function(e) { self.keydown(e);};
Struppi.
Hallo,
Objektorientierung beißt sich mit dem Konzept von Event-Handlern. Wenn du eine Objektmethode auf die Weise als Handler registrierst, hat sie mit dem Objekt nix mehr zu tun, es sei denn, du sorgst dafür, dass die Objektinstanz per Closure-Effekt darin verfügbar ist (darauf läuft Struppis Lösung hinaus). Das ist eigentlich nur ein Hack.
In Prototype gibts dafür eine Standardlösung (wie für vieles, aber niemand kennt und benutzt es - vielleicht kennst du meine Meinung zu Bibliotheken). Ich bin kein Bibliotheken-Kenner, aber prinzipiell geht das in Prototype meines Wissens so:
Event.observe(element, "keydown", this.keydown.bindAsEventListener(this));
Das kapselt die Handlerfunktion im Grunde auch nur in einer Closure und führt den Handler im Kontext von this aus. Ist natürlich ewig langer Code.
Allerdings ist dein Ansatz anscheinend eher verquert und diese Objektorientierung bringt in dem Fall keinen Vorteil, genausowenig scheint es mir angesichts deines Codes nötig, dass der Handler im Kontext der Objektinstanz ausgeführt wird. Wird er dies nämlich nicht, wird er im Kontext des input-Elementes ausgeführt, und dieses ist in der Handlerfunktion als this verfügbar. Du kannst darüber also sowohl das maxLength-Attribute als auch den value auslesen. (Wenn du das maxLength-Attribut vorher löschen willst, kein Problem, dann speicherst du den Wert halt in einer anderen Eigenschaft beim Elementknoten-Objekt und kannst im Handler trotzdem darauf zugreifen.)
Mathias