Globale Vars / Vars übergeben
Markus Speicherl
- javascript
Guten Abend
Ich habe mir mootools runtergeladne und arbeite gerade mit der Slider-Funktion. Doch ich glaube das ist eher nebensächlich. Da sProblem welches ich habe ist, das ich eine var nicht übergeben bekomme, bzw nicht es hinbekomme sie global zu setezn.
window.addEvent('domready', function(){
var slider = new Array();
var entrys = new Array('RW','RD','RH');
var values = new Array();
values['RW'] = new Array(450,50,800);
values['RD'] = new Array(450,50,800);
values['RH'] = new Array(350,50,600);
for (var i=0;i<entrys.length;i++){
var dID = entrys[i];
slider[i] = new Slider($(dID+'bar'), $(dID+'but'), {
start: values[dID][1],
end: values[dID][2],
onChange: function(step,dID){
$(dID+'val').setHTML(step);
}
}).setMin(values[dID][0]);
}
});
Im grunde dreht es sich nur um diesen Abshcnitt:
onChange: function(step,dID){
$(dID+'val').setHTML(step);
}
Ich bekomme es nicht hin, dass in dieser Funktion dID übergeben bzw. ausgegeben wird. JS liefert mir jedesmal einen Fehler und sagt es wäre nicht defniert.
Ich probierte auch schon aus, dass ich es nicht übergebe, da dID ja schon oben _ausserhalb_ der Funktion defniert wurde und somit eigentlich global für die Funktion sein müste.
Ich habe auch schon folgendes Probiert:
onChange: function(step){
$(entrys[i]+'val').setHTML(step);
}
onChange: function(step,i){
$(entrys[i]+'val').setHTML(step);
}
Hat jemand eine Ahnung wie ich dieser Funktion mitteile wi es an den zu übergeben string kommt?
ich eine var nicht übergeben bekomme, bzw nicht es hinbekomme sie global zu setezn.
for (var i=0;i<entrys.length;i++){
var dID = entrys[i];
slider[i] = new Slider($(dID+'bar'), $(dID+'but'), {
start: values[dID][1],
end: values[dID][2],
onChange: function(step,dID){
$(dID+'val').setHTML(step);
}
}).setMin(values[dID][0]);
Im grunde dreht es sich nur um diesen Abshcnitt:
onChange: function(step,dID){
$(dID+'val').setHTML(step);
}Ich bekomme es nicht hin, dass in dieser Funktion dID übergeben bzw. ausgegeben wird. JS liefert mir jedesmal einen Fehler und sagt es wäre nicht defniert.
Die Anleitung zu dieser Eigenschaft ist in der Tat wenig hilfreich, wenn Du aber mal in den Slider-Quelltext schaust, wirst Du ganz am Ende folgendes finden:
checkStep: function(){
if (this.previousChange != this.step) {
this.previousChange = this.step;
this.fireEvent('onChange', this.step);
}
},
Das ist die Stelle, an der die Slider-Klasse via fireEvent() Deine onChange-Funktion aufruft, und wie Du siehst, mit nur einem Argument, nicht zweien.
Ich probierte auch schon aus, dass ich es nicht übergebe, da dID ja schon oben _ausserhalb_ der Funktion defniert wurde und somit eigentlich global für die Funktion sein müste.
Nein, die onChange-Funktion läuft in ihrem eigenen Kontext. In der Schleife definierst Du lediglich den Code der Funktion, ablaufen tut er erst später, unabhängig von der Schleife und damit ohne die Variablen, die in der Schleife existieren.
Ich habe auch schon folgendes Probiert:
onChange: function(step){
$(entrys[i]+'val').setHTML(step);
}
Gleiches Problem: Die Variable i existiert in der Schleife, aber nicht in der Funktion.
onChange: function(step,i){
$(entrys[i]+'val').setHTML(step);
}
Gleiches Problem wie eingangs: Die onChange-Funktion wird mit nur einem Argument übergeben.
Hat jemand eine Ahnung wie ich dieser Funktion mitteile wi es an den zu übergeben string kommt?
Die Variable this sollte in der onChange-Funktion auf das zugehörige Slider-Objekt zeigen. Du müsstest also auf this.element und this.knob (die beiden ersten Argumente bei new Slider()) zugreifen können:
slider[i] = new Slider($(dID+'bar'), $(dID+'but'), {
start: values[dID][1],
end: values[dID][2],
onChange: function(step){
$(irgendwie_die_ID_eines_Elements_holen_und_um_'bar'_kürzen(this.element)+'val').setHTML(step);
}
});
Womöglich kannst Du sogar eigene Optionen übergeben, die dann über this.options.bla ansprechbar sind, etwa so:
slider[i] = new Slider($(dID+'bar'), $(dID+'but'), {
start: values[dID][1],
end: values[dID][2],
bla: dID,
onChange: function(step){
$(this.options.bla+'val').setHTML(step);
}
});
Das ist aber nur eine Vermutung.
Gruß, Hannes.
Hallo,
Da warst du wohl schneller, ich hatte das Posting einmal versemmelt und dann nicht nachgeschaut, ob schon jemand anderes geantwortet hatte. ;)
Nein, die onChange-Funktion läuft in ihrem eigenen Kontext. In der Schleife definierst Du lediglich den Code der Funktion, ablaufen tut er erst später, unabhängig von der Schleife und damit ohne die Variablen, die in der Schleife existieren.
Leider sind sie durch den Closure-Effekt in der onChange-Funktion durchaus verfügbar. Da die Slider aber in einer Schleife liegt, zeigt dID in der onChange-Funktion auf den letzten erzeugten Slider, also ist es nicht brauchbar.
Die Variable this sollte in der onChange-Funktion auf das zugehörige Slider-Objekt zeigen. Du müsstest also auf this.element und this.knob (die beiden ersten Argumente bei new Slider()) zugreifen können
Ja, das geht; wobei ich es für einfacher halte, die ID einfach direkt am Objekt zu speichern, dann spart man sich das Extrahieren der ID aus den ID der anderen Elemente.
Womöglich kannst Du sogar eigene Optionen übergeben, die dann über this.options.bla ansprechbar sind
Japp, auch eine Möglichkeit. Jetzt verstehe ich auch, warum Markus die Options start und end gesetzt hatte... dann hatte er die Lösung im Grunde ja schon selbst gefunden. ;)
Mathias
Hallo,
var slider = new Array();
var entrys = new Array('RW','RD','RH');
var values = new Array();
values['RW'] = new Array(450,50,800);
values['RD'] = new Array(450,50,800);
values['RH'] = new Array(350,50,600);
Pfui! So macht man das nicht. Das macht man semantisch mit Objects (du benutzt ein Mischmasch, weil du Arrays und »assoziative Arrays« kennst, aber in JavaScript läuft der Hase etwas anders):
~~~javascript
var sliders = {
RW : {
initial : 450,
start : 50,
end : 800
},
usw.
};
Das durchläufst du dann mit einer for-in-Schleife und auf die Werte greifst du als Unterobjekte zu;
for (var name in sliders) {
var currentSlider = sliders[name];
alert(name + "\n"+ currentSlider.initial + "\n" + currentSlider.start + usw.);
}
Das nur zum Stil.
for (var i=0;i<entrys.length;i++){
var dID = entrys[i];
slider[i] = new Slider($(dID+'bar'), $(dID+'but'), {
start: values[dID][1],
end: values[dID][2],
onChange: function(step,dID){
$(dID+'val').setHTML(step);
}
}).setMin(values[dID][0]);}
});
Der onChange-Handler wird im Kontext des Slider-Objektes ausgeführt, also speichern wir die ID doch einfach dort, damit wir im Handler darauf Zugriff haben.
~~~javascript
var changefunc = function (step) {
alert(this.id + "\n" + step);
// Hier geht dann:
$(this.id + "val").setHTML(step);
};
var newSlider = new Slider(
$(dID + 'bar'),
$(dID + 'but'),
{
start : values[dID][1],
end: values[dID][2],
onChange: changefunc
}
);
newSlider.set(values[dID][0]);
newSlider.id = dID;
slider[i] = newSlider;
Das Slider-Objekt hat übrigens noch weitere interessante öffentliche Eigenschaften, darunter element und knob, Referenzen auf die beiden Elementobjekte. Darüber hätte man im Notfall auf die ID rauskriegen können.
P.S. Laut mootools-Doku nimmt der Slider-Konstruktor keine options namens start und end an und es gibt eine set-, aber keine setMin-Methode. Aber vielleicht benutzt du irgendeine Beta- oder angepasste Version...
Mathias
Guten Abend
Vielen Dnak erstmal euch beiden. Das war schonmal sehr aufschlussreich.
Vorweg kann ich schonmal auflösen: Ich benutze eine modifizierte slider.js von einem dritten weil ich einen mootool-slider erstellen wollte der einen fixen startwert hat den man nicht unterschreiten soll und die slider.js von mootools dies von haus aus nicht mitliefert.
Doch zum Problem:
(Nebenbei: Ich fand das mit dem Hinweis auf den Stil sehr interessantm danke)
Ich habe jetzt meinen Code nochmal mit deinem Ansatz umgestrickt und er sieht nun so aus:
var sliders = {
RW : {
initial : 450,
start : 50,
end : 800
},
RD : {
initial : 450,
start : 50,
end : 800
},
RH : {
initial : 450,
start : 50,
end : 800
}
};
var slider = new Array();
for (var name in sliders) {
var dID = sliders[name];
//alert(name + "\n"+ dID.initial + "\n" + dID.start + "\n" + dID.end);
var changefunc = function (step) {
//alert(this.id + "\n" + step);
// Hier geht dann:
$(this.id + "val").setHTML(step);
};
var newSlider = new Slider($(dID+'bar'),$(dID+'but'),{
start : dID.start,
end: dID.end,
onChange: changefunc
}
);
//Dieser Wert muss setMin heissen, da die Modifizierte
//Slider.js keine einfaches .set unterstüzt
newSlider.setMin(dID.initial);
newSlider.id = dID;
slider[dID] = newSlider;
}
Allerdings kam ich damit jetzt ins schlingern und er sagt kien fehler mehr, aber die Slider arbeiten auch nicht.
Ich habe sie deswegen nochmal kompeltt umgestrickt damit sie dem originalen Mootools-Code am ähnlichsten sieht und deinen Rat beherzigt...
var sliders = {
RW : {
initial : 450,
start : 50,
end : 800
},
RD : {
initial : 450,
start : 50,
end : 800
},
RH : {
initial : 350,
start : 100,
end : 1000
}
};
var slider = new Array();
for (var name in sliders) {
var dID = sliders[name];
var dNA = name;
//alert(dNA + "\n"+ dID.initial + "\n" + dID.start + "\n" + dID.end);
var changefn = function (step) {
//alert(dNA + "\n" + step);
$(this.id + "val").setHTML(step);
};
var newSlider = new Slider($(dNA+'bar'), $(dNA+'but'), {
start: dID.start,
end: dID.end,
onChange: changefn
});
newSlider.setMin(dID.initial);
newSlider.id = dNA;
slider[dNA] = newSlider;
}
Allerdings geht auch das nicht.
Ich nahm dann mal das this.id aus changefn raus und ersetze es mit dNA
var changefn = function (step) {
//alert(dNA + "\n" + step);
$(dNA + "val").setHTML(step);
};
Siehe da, alle Slider werden korrekt voreingestellt und lassen sich ziehen. Leider leider wird leider nur immer der Wert RH geändert um die neue Position anzuzeigen. Dies lässt nur einen schluss zu: RH ist das letzte Glied in der Kette und bleibt beim steten überschreiben wohl immer als letztes übrig weswegen alle änderungs-übergaben immer an RH gehen.
Doch wie mache ich das nun? Denn this.id scheint ja nicht zu gehen. Oder liegt der Fehler doch noch im Detail?
Grüsse
Hallo,
Leider leider wird leider nur immer der Wert RH geändert um die neue Position anzuzeigen.
Im zweiten Posting habe ich erklärt, warum genau das eben nicht geht - man kann hier keine Closures nutzen.
Doch wie mache ich das nun?
Fehlersuche! ;)
id ist nicht gesetzt. id wird aber gesetzt. Also wird id erst dann gesetzt, wenn die onChange-Funktion schon einmal ausgeführt wurde. Warum? Weil erst setMin() aufgerufen wird und dann die id-Eigenschaft gesetzt wird. setMin() führt die onChange-Funktion aber schon aus.
Also vertauschen wir die Reihenfolge, diesmal so herum:
newSlider.id = dNA;
newSlider.setMin(dID.initial);
(Hättest du jetzt auch drauf kommen können... ;))
Mathias
*schlägt sich vor den Kopf*
Das geht doch nicht klar... mist =)
Danke für die Lösung.
Ich habe noch einen nachtrag:
Wie kann ich denn jetzt von ausserhalb diese Slider ansprechen? Ich möchte einen link einbauen der die slider auf ihre Grundwerte zurückstellt und mir wird nicht klar wie ich die einzelnen Slider (oder auch alle) ansprechen kann und mit welchem Befehl (step? setstep?) ich die Werte zuweisen kann.
grüsse
Hallo,
Wie kann ich denn jetzt von ausserhalb diese Slider ansprechen? Ich möchte einen link einbauen der die slider auf ihre Grundwerte zurückstellt
Du speicherst die Slider-Objekte ja im Array slider, den musst du dann global machen, indem du »var« davor weglässt.
Diesen Array kannst du durchlaufen und für jeden Slider sliderobjekt.set(sliderobjekt.options.start) aufrufen (hat Hannes im Grunde schon beschrieben).
Mathias
Mh, dank dir herzlich.
Aber irgendwie hapert es da noch an meinem verständnis dass ich es hinbekomme dass das funktioniert.
So wollte ich die Funktion jetzt ausserhalb des DOMREADY setzen und weiss aber nicht wie ich von dort aus an die Slider komme. Ich müsste sie also innerhalb defnieren. Aber dann komme ich nichtmehr ausserhalb an die vars.
Ich denke ich lass es so, bedanke mich herzlichst bei dir und lese mich erstmal weiter ein =)
grüsse und danke nochmal