Problem mit for-Schleife und shift()?
merul
- javascript
Hallo!
Ich möchte Fragebögen dynamisch mittels Javascript erstellen. Fragen und Antworten sind in einem Array genauso wie die verschiedenen Fragenkombinationen für die Fragebögen. Die entsprechende Funktion sind bisher wie folgt aus:
Kombination = new Array(16); // Jedes Element des Arrays enthält die vorgeschriebenen Fragenkombis als Arrays.
Fragen = new Array(99); // Array für die Fragen und Antworten. jedes Element ist wiederum ein Array, wobei dort jeweils das erste Element immer die Frage ist, das zweite immer die richtige Antwort.
Fragen[1] = new Array("Der wie vielte Bundespräsident ist Joachim Gauck?", "der 11.", "der 9.", "der 10.", "der 12."); // Beispiel für eine solche Frage
function fragen(n) { // n ist die Nr. des Fragebogens und wird bei Aufruf übergeben
Kombination[n].shuffle(); // "shuffle()" (s. unten. Bei mir auf dem Rechner ist's vor dieser Funktion.) ist aus dem Inet gesucht, um die Elemente des Arrays, also die Fragen der Fragebögen, zu mischen.
document.write("<form name=\"Fragebogen\" action=\"\">\n");
for (var i = 0; i < Kombination[n].length; i++){
var antw = Fragen[Kombination[i]][1]; // die richtige Antwort wird gesichert, bevor die Antworten gemischt werden.
var frage = Fragen[Kombination[i]].shift(); // das erste Element, also die Frage, wird entfernt und "frage" übergeben, damit die Antworten gemischt werden können.
Fragen[Kombination[i]].shuffle(); // die Antworten werden gemischt.
document.write("<p>" + (i+1) + ". " + frage + "<br><br>\n");
for (var k = 0; k < 4; k++) { // es gibt immer genau vier Antworten.
document.write("<input type=\"radio\" name=\"Frage_" + (i+1) + "\" value=\"");
if (Fragen[Kombination[i]][k] == antw)
{document.write("1");}
else {document.write("0");}; // unterschiedliche values dienen der Auswertung (1 steht für richtige Antwort.)
document.write("\">" + Fragen[Kombination[i]][k] + "<br>\n");
};
document.write("</p><br>\n");
};
document.write("<input type=\"button\" name=\"Auswertung\" value=\"Auwertung\" onclick=\"auswertung();\">\n<\/form>");
return true;
}
Array.prototype.shuffle = function() {
var s = [];
while (this.length) s.push(this.splice(Math.random() * this.length, 1)[0]);
while (s.length) this.push(s.pop());
return this;
}
Mein Problem ist jetzt, dass es bei jedem Aufruf der Funktion Fragen (bisher jeweils frühestens die 6.) gibt, bei denen die vierte, manchmal auch die dritte und die vierte Antwort als "undefined" ausgegeben und anstatt der Frage eine Antwort hingeschrieben werden. Meines Erachtens bedeutet das, dass mir "shift()" irgendwie mehr Elemente "klaut", als ich eigentlich will. Also muss der Fehler wahrscheinlich in der (ersten?) for-Schleife stecken.
Ich finde ihn aber irgendwie nicht. Könntet ihr mir vielleicht helfen? :)
Viele Grüße und vielen Dank schon mal
merul
Hallo merul,
vielleicht verstehe ich ja deinen Code nicht, aber hier
> for (var i = 0; i < Kombination[n].length; i++){
> var antw = Fragen[Kombination[i]][1]; // die richtige Antwort wird gesichert, bevor die Antworten gemischt werden.
> var frage = Fragen[Kombination[i]].shift(); // das erste
läuft i von 0 bis Kombination[n].length - 1, du benutzt es dann aber als Index von Kombination. Hat Kombination so viele Elemente, wie Kombination[n]?
Gruß, Jürgen
Hallo merul,
vielleicht verstehe ich ja deinen Code nicht, aber hier
for (var i = 0; i < Kombination[n].length; i++){ var antw = Fragen[Kombination[i]][1]; // die richtige Antwort wird gesichert, bevor die Antworten gemischt werden. var frage = Fragen[Kombination[i]].shift(); // das erste
> läuft i von 0 bis Kombination[n].length - 1, du benutzt es dann aber als Index von Kombination. Hat Kombination so viele Elemente, wie Kombination[n]?
>
> Gruß, Jürgen
Hallo Jürgen,
Ja, da hast du recht, da fehlt was. ^^ Vielen Dank für den Hinweis! Das ist durch die Änderung der Variablennamen geschehen, die ich für das Forum vorgenommen habe, um es etwas verständlicher zu machen. Richtig ist die Funktion deshalb wie folgt:
~~~javascript
function fragen(n) { // n ist die Nr. des Fragebogens und wird bei Aufruf übergeben
Kombination[n].shuffle(); // "shuffle()" (s. unten. Bei mir auf dem Rechner ist's vor dieser Funktion.) ist aus dem Inet gesucht, um die Elemente des Arrays, also die Fragen der Fragebögen, zu mischen.
document.write("<form name=\"Fragebogen\" action=\"\">\n");
for (var i = 0; i < Kombination[n].length; i++){
var antw = Fragen[Kombination[n][i]][1]; // die richtige Antwort wird gesichert, bevor die Antworten gemischt werden.
var frage = Fragen[Kombination[n][i]].shift(); // das erste Element, also die Frage, wird entfernt und "frage" übergeben, damit die Antworten gemischt werden können.
Fragen[Kombination[n][i]].shuffle(); // die Antworten werden gemischt.
document.write("<p>" + (i+1) + ". " + frage + "<br><br>\n");
for (var k = 0; k < 4; k++) { // es gibt immer genau vier Antworten.
document.write("<input type=\"radio\" name=\"Frage_" + (i+1) + "\" value=\"");
if (Fragen[Kombination[n][i]][k] == antw)
{document.write("1");}
else {document.write("0");}; // unterschiedliche values dienen der Auswertung (1 steht für richtige Antwort.)
document.write("\">" + Fragen[Kombination[n][i]][k] + "<br>\n");
};
document.write("</p><br>\n");
};
document.write("<input type=\"button\" name=\"Auswertung\" value=\"Auwertung\" onclick=\"auswertung();\">\n<\/form>");
return true;
}
Das produziert allerdings den im Ausgangspost schon beschriebenen Fehler. :/
Viele Grüße
merul
Hi,
Ich möchte Fragebögen dynamisch mittels Javascript erstellen. Fragen und Antworten sind in einem Array genauso wie die verschiedenen Fragenkombinationen für die Fragebögen. Die entsprechende Funktion sind bisher wie folgt aus:
das bringt mich auf die ganz wichtige Frage: Wie wird diese Funktion aufgerufen? Denn du verwendest da eifrig document.write(), das dir hier möglicherweise Ärger macht.
document.write("<form name=\"Fragebogen\" action=\"\">\n");
document.write("<p>" + (i+1) + ". " + frage + "<br><br>\n"); document.write("<input type=\"radio\" name=\"Frage_" + (i+1) + "\" value=\""); {document.write("1");} else {document.write("0");}; // unterschiedliche values dienen der Auswertung (1 steht für richtige Antwort.) document.write("\">" + Fragen[Kombination[i]][k] + "<br>\n"); document.write("</p><br>\n");
document.write("<input type="button" name="Auswertung" value="Auwertung" onclick="auswertung();">\n</form>");
Wenn document.write() aufgerufen wird, \*während\* der Browser den Quelltext parst und das Dokument rendert, geht das klar. Wenn document.write() aber \*nach\* dem Rendern des Dokuments nochmal aufgerufen wird, dann \*ersetzt\* es das bisherige Dokument mit dem neu ausgegebenen Text.
Ciao,
Martin
--
Frage an Radio Eriwan: Kann man eigentlich ein guter Kommunist und gleichzeitig ein guter Christ sein?
Radio Eriwan antwortet: Im Prinzip ja - aber warum sollte man sich das Leben doppelt schwer machen?
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
Wenn document.write() aufgerufen wird, *während* der Browser den Quelltext parst und das Dokument rendert, geht das klar. Wenn document.write() aber *nach* dem Rendern des Dokuments nochmal aufgerufen wird, dann *ersetzt* es das bisherige Dokument mit dem neu ausgegebenen Text.
Hallo! Danke für den Hinweis! Ich habe deshalb jetzt mal zuerst versucht, die Elemente mittels createNode usw. in das aktuelle Dokument zu schreiben. Das hat funktioniert, es kam dennoch an einigen Stellen zu "undefined". Danach hab ich dann document.write im body verwendet. Die einzelnen Fragebögen hätte ich am Ende über style="display:none;" unsichtbar gemacht und über Klick sichtbar gemacht. Aber auch da fehlten Antworten ...
Letztlich ist mir gerade folgendes aufgefallen: Die fehlenden Elemente treten nur bei den Fragen auf, die doppelt oder öfter im Kombinationsarray vorkamen. Ich hatte zu Probezwecken lediglich zwei Kombinationen erstellt und -- da noch nicht alle Fragen in Arrays abgelegt sind -- wohl einige Fragen zwei oder mehrere Male in die Kombinationsarrays geschrieben.
Habe ich jede Frage nur einmal in der jeweiligen Kombination, funktioniert es ... Grund dafür dürfte sein, dass ich Fragen[...].shift() verwende. Dadurch wird bei einem erneuten Durchlauf die schon um eine Antwort gekürzte Frage erneut gekürzt. Um Fragen doppelt verwenden zu können, müsste ich deshalb eine Kopie des Arrays verwenden.
Viele Grüße
merul
PS: Wie schließe ich Threads oder zeige an, dass das Problem gelöst ist? :)
Hallo,
PS: Wie schließe ich Threads ...
gar nicht, das erledigt sich von allein, wenn einige Tage lang keine Beiträge mehr dazukommen. Dann wandert der Thread ab ins Archiv.
... oder zeige an, dass das Problem gelöst ist? :)
Genau so, wie du es gerade getan hast. Wenn man es ganz toll machen möchte, ändert man noch den Posting-Titel vor dem Absenden, so dass andere schon das Ergebnis sehen, bevor sie den Beitrag aufrufen.
So long,
Martin