• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[GELÖST] setInterval und clearInterval in verschiedenen Funktionen kombinieren

JohannesV

New member
Liebe Forumsbesucher und Moderatoren,

nachdem Ihr mir letztens sehr schnell und freundlich geholfen habt :D, habe ich hier eine weitere Frage, die ich auch mit hartnäckigen Versuchen nicht selbst lösen konnte. :confused:
Ich möchte, dass während des Drückens einer Taste etwas regelmäßig geschieht (zum Beispiel, dass sich ein Cursor gleichmäßig bewegt). Nach meinen JavaScript-Kenntnissen geht das, indem bei onkeydown ein setInterval eingerichtet wird und bei onkeyup ebendieses durch clearInterval aufgelöst wird. Eine Variable namens "Aktiviert" sorgt dafür, dass setInterval bei onkeydown auch bei langem Drücken nur einmal gemacht wird (ich glaube, man nennt so etwas flag).
Ich versuchte es wie folgt:
Code:
var Aktiviert = false;

document.body.onkeydown = function (event) {
var Richtung = event.keyCode;
if (Richtung == 37) { //Linkspfeil wurde gedrückt
if (Aktiviert == false) { //Bei langem Drücken nur einmal setInterval machen
var Regel = setInterval(function() {Bewegung()}, 40);
return Regel;
Aktiviert = true; return Aktiviert;}}}

document.body.onkeyup = function (event) {
var Richtung = event.keyCode;
if (Richtung == 37) { //Linkspfeil wurde wieder losgelassen
clearInterval(Regel);
Aktiviert = false; return Aktiviert;}}

function Bewegung () {
var Cursor = document.getElementById('Cursor');
Cursor.style.left = Number(Cursor.style.left.replace('px',''))-8+'px';} //Alle 40ms geht der Cursor 8px nach links.
Doch onkeyup funktioniert nicht. Ich nehme an, dass var Regel nicht richtig übergeben wird, sodass dem Browser bei onkeyup nicht bewusst ist, auf was sich clearInterval bezieht. Habe ich einmal die Pfeiltaste gedrückt, geht der Curser auch nach Loslassen der Taste immer weiter. Eigentlich sollte der Cursor nach dem Loslassen der Pfeiltaste stehen bleiben. Wie kann ich es lösen, dass in der Funktion onkeydown {} ein setInterval bestimmt und genau dieser Timer in der Funktion onkeyup {} wieder beendet wird?

Ich habe im Forum intensiv gesucht, ob die Frage schon einmal so oder so ähnlich gestellt wurde, und nichts gefunden. Falls doch schon Antworten existieren, bitte ich um einen kurzen Verweis.
Vielen Dank für Eure Hilfe!

Johannes
 
Das Problem ist, dass die Variable Regel innerhalb der anonymen Funktion bei keydown definiert wird. Außerhalb ist sie deshalb nicht sichtbar. Um das Problem zu lösen, musst Du diese Variable außerhalb der Funktion definieren.
 
Herzlichen Dank an CT24 und Sempervivum!
Zwei simple Antworten, eine simple Lösung - und schon funktioniert es. Dabei hat es mir gut getan, dem Link zu folgen und noch einmal den Unterschied zwischen lokaler und globaler Variable nachzulesen.

Noch ein Hinweis: Der Code funktionierte erst, als ich "return Regel" entfernte. Diese Aussage war aber für die Funktion offenbar nicht nötig. Durch Ausprobieren habe ich gemerkt, dass es auch ohne "return Aktiviert" geht.

Wie kann ich bei meiner Frage den Status auf "gelöst" setzen?
 
Wie kann ich bei meiner Frage den Status auf "gelöst" setzen?
Erledigt.

PS: du solltest deinen Code unbedingt strukturieren und vernünftig einrücken!
PPS: Variablen und Funktionsnamen werden, sofern sie kein Konstruktor sind, im Allgemeinen klein geschrieben. Diese Namenskonvention wird auch im JS-Core verwendet und von vielen benutzt; daher erleichtert sie das Verstehen des Codes.
PPPS: var Regel = setInterval(function() {Bewegung()}, 40); kann man noch verbessern und verkürzen: var Regel = setInterval(Bewegung, 40);
PPPPS: statt Number() sollte man besser parseInt() verwenden.
PPPPPS:
Du musst einfach eine Globale Variable erstellen in die du das Interval nacher rein haust
Generell sind globale Variablen eine sehr schlechte Idee und man sollte sie unbedingt vermeiden. Brauchen tust du sie außerdem nicht; die Variable muss sich lediglich im zugreifbaren Scope befinden:
Code:
	var moveCursor = function moveCursor(ev) {
		if (ev.keyCode === 37) { //Linkspfeil wurde gedrückt
			var move = setInterval(function() {
				var cursor = document.getElementById('cursor');
				cursor.style.left = parseFloat(cursor.style.left, 10) + 8 + "px";
			}, 40);
			document.onkeydown = null;
		}
		document.onkeyup = function(ev) {
			if (ev.keyCode === 37) { //Linkspfeil wurde wieder losgelassen
				clearInterval(move);
				document.onkeydown = moveCursor;
			}
		};
	};
	document.onkeydown = moveCursor;



Übrigens: Eigentlich brauchst du gar kein Interval:
HTML:
<script src="https://raw.githubusercontent.com/j-l-n/jln.js/master/jln.js"></script>
<script src="https://raw.githubusercontent.com/j-l-n/jln.js/master/modules/jln.event.js"></script>

<script>
ready(function(){
	var cursor = document.getElementById('cursor');
	jln.event.bind("keydown", function(ev){
		if(ev.keyCode === 39){ //nach rechts schieben
			var marginLeft;
			if(cursor.style.left === ""){
				marginLeft = "5px";
			}
			else{
				marginLeft = parseFloat(cursor.style.left, 10) + 5 + "px";	
			}
			cursor.style.left = marginLeft;
		}
	});
});
</script>

<div style="background-color:red;position:absolute;width:20px;height:20px;" id="cursor"></div>
 
Zurück
Oben