timer in een loop of functie gebruiken

Status
Niet open voor verdere reacties.

ArjanvanRijs

Gebruiker
Lid geworden
9 mrt 2016
Berichten
26
Hallo allemaal,

ik ben nieuw hier en bezig met het leren van javascript. Ik heb al het nodige geschreven en krijg meestal de zaken wel werkend, maar in dit geval snap ik er even niets meer van. Ik probeer een functie te schrijven die een element (<p>, <img> enz...) opent in een gegeven aantal seconden. Ja, ik weet dat JQuery ook dit soort functionaliteit biedt, maar wil het graag zelf snappen en leren hoe het werkt.
In ieder geval heb ik heel wat zitten lezen op fora en in mijn boeken en ben er achter gekomen dat het verstandig is om een aparte timer te maken, die vervolgens door de functies die een timer nodig hebben wordt gechecked. Tot zover geen probleem. Ik heb een timer die elke 20 ms een teller ophoogt met 1. Als ik deze timer bij het initialiseren activeer en vervolgens bij click-events de waarde opvraag krijg ik die gewoon. Maar... zodra ik de waarde opvraag in een loop (of een functie) blijft de waarde vanaf dat moment gelijk. Dit lijdt dus tot oneindige loops en vreemde foutmeldingen.
Weet iemand wat ik fout doe? Hieronder de definitie van de timer:

[js]
function Timer() {
if(typeof Timer.timerwaarde == 'undefined') {
Timer.timerwaarde = 0;
} else {
Timer.timerwaarde++;
}
setTimeout(Timer, 20);
}
[/js]

binnen de functie is het volgende opgenomen:

[js]
if(typeof Timer.timerwaarde != 'undefined') {
var timer = Timer.timerwaarde;
} else {
Timer();
var timer = Timer.Timerwaarde;
}
[/js]

Ik hoop dat iemand me kan helpen.

Met vriendelijke groet,
Arjan van Rijs.
 
Laatst bewerkt:
Niet getest dus je moet de syntax nog in orde maken, maar het gaat om het idee.
Code:
function Timer(GetValue) {
   if (typeof Interval === 'undefined') {
      var Timerwaarde = 0;
      var Interval = setInterval(Timer(false), 20);
   } else if (GetValue == false) {
      Timerwaarde++;
   } else {
      return Timerwaarde;
   }
 }

// in een andere functie:

var Timerwaarde = Timer(true)
Suc6. Have fun.
 
Laatst bewerkt:
Dank voor het meedenken, Bron (heb ik nu dan source-code te pakken;-)

In eerste instantie deed 'ie niets. De waarden bleven bij iedere itteratie 'undefined'. Nu heb ik de functie een beetje aangepast en toen werkte die...
precies zoals mijn functie ook deed. Zucht...

[js]
function Timer(GetValue) {
if (typeof Timer.interval === 'undefined') {
Timer.Timerwaarde = 0;
Timer.interval = setInterval("Timer(" + false + ")", 20);
}
if (GetValue == false) {
Timer.Timerwaarde++;
} else {
return Timer.Timerwaarde;
}
}
[/js]

Probeer maar met een simpele functie zoals:

[js]
function Bla(naam) {
if(naam && naam != '') {
var timer = Timer(true);
alert('blablabla, ' + naam + '. De timerwaarde is: ' + timer);
}
}


//i.c.m. dit
<form>
<label for="naam">
Naam:
<label>
<input id="naam" name="naam" type="text" onchange="Bla" />
</form>
[/js]

maar in een recursieve functie - en ik denk dat timerafhankelijke functies dat per definitie zijn - blijft de timerwaarde 0, hoe vaak je ook ittereert.

Ik vermoed dat het te maken heeft met closure of binding, maar ik kom er niet precies achter wat dat is.

Met vriendelijke groet,

Arjan
 
Laatst bewerkt:
Top :thumb: mooi dat het werkt.
Je hebt een recursieve functie zonder "if" om te stoppen. De "if" is in dit geval: de browser afslutien.

setInterval(Timer, 20, false) om false als param aan de function te geven (behalve bij ie9).
 
Laatst bewerkt:
Top :thumb: mooi dat het werkt.
Je hebt een recursieve functie zonder "if" om te stoppen. De "if" is in dit geval: de browser afslutien.

setInterval(Timer, 20, false) om false als param aan de function te geven (behalve bij ie9).

Maar het werkt dus niet!!!

Als ik de timerwaarde ophaal vanuit een andere (recursieve) functie dan krijg ik hele vreemde foutmeldingen zoals 'toegang geweigerd' op simpele for-voorwaarden en syntaxisfouten op brackets die gewoon correct zijn genest. Nogmaals, ik vermoed dat het te maken heeft met closure, maar dat weet ik niet zeker en ik weet niet wat daar precies mee bedoeld wordt...

Kan iemand me daarmee helpen?

Vriendelijke groet,

Arjan.
 
Misschien dat dit het probleem duidelijk maakt:

[js]
<!DOCTYPE HTML>
<html lang="nl">
<head>
<title>Bla</title>

<script type="text/javascript">
//<![CDATA[
function Timer(init) {
if(init == true) {
timer = 0;
Timer.handler = setInterval("Timer(" + false + ")", 20);
} else if(init == 'stop') {
clearInterval(Timer.handler);
} else {
timer++;
}
}

function init() {
Timer(true);
var veld = document.getElementById('veld');
veld.onfocus = bla;
}

function bla() {
alert('Timer: ' + timer);

/* do {
document.writeln('Timer: ' + timer + '<br />');
} while(timer < 200)*/
}

window.onload = init;
//]]>
</script>
</head>
<body>
<form>
<input id="veld" type="text" />
</form>
</body>
</html>
[/js]


Probeer het eerst zoals hier is afgebeeld en daarna met de 'uitgecommentarieerde' do-while loop. In het eerste geval gaat alles prima. In het tweede geval creëer je een oneindige loop.:confused:

Wie, oh wie?

Vriendelijke groet,
Arjan.
 
Een simpel script wat ik net heb gemaakt en wat werkt. Je kunt starten, stoppen en de waarde uiitlezen.
Code:
<script>
function Timer(Reset) {
	if (typeof Reset === 'undefined') {
		return ItvWaarde;
	} else if (Reset) {
		clearInterval(ItvTimerId);
		ItvWaarde = undefined; //netter is de volgende regel
		//ItvWaarde = (function(){ return; })();
	} else {
		if (typeof ItvWaarde === 'undefined') ItvWaarde = 0;
		ItvTimerId = setInterval(function(){ ItvWaarde++; }, 20);
	}
}
function GetValue() {
	document.getElementById("resultaat").innerHTML = Timer();
}
</script>
<button onclick="Timer(false)">Init timer</button>
<button onclick="Timer(true)">Stop timer</button>
<button onclick="GetValue()">Toon waarde</button>
<p id="resultaat">undefined</p>
Noot: omdat ItvTimerId en ItvWaarde geen var in de functie hebben komen deze in de global scope.

Suc6. Have fun.
 
Hoi Bron,

dank je wel voor het meedenken. Helaas is het resultaat hetzelfde. Probeer maar eens deze code

[js]
function func() {
do {
var timer = Timer();
document.writeln('Timer: ' + timer + '<br />');
} while(timer < 200)
}
[/js]

aan de [Toon waarde] button te koppelen. Weer een oneindige loop.
In mijn code (vorige bericht) had ik trouwens ook al een globale variabele gebruikt voor de timerwaarde.
Maar dit is wat programmeren leuk maakt, toch? Als het alleen maar codekloppen is is er iets niet goed...

We blijven proberen!

Vriendelijke groet,
Arjan.
 
Je hebt geen controle over de do-while loop. Het beste kan je actie(s) in Timer(..) zetten (of je haalt dit deel eruit en zet het in een aparte function). In onderstaande code vinden acties alleen plaats als de interval is afgelopen en opnieuw begint.
Code:
<script>
function Timer(Reset) {
   if (typeof Reset === 'undefined') {
      return ItvWaarde;
   } else if (Reset) {
      clearInterval(ItvTimerId);
      ItvWaarde = undefined;
   } else {
      if (typeof ItvWaarde === 'undefined') ItvWaarde = 0;
      ItvTimerId = setInterval(function(){
         if (ItvWaarde < 200) {
            ItvWaarde++;
            ToonWaarde(ItvWaarde);
         } else {
            clearInterval(ItvTimerId);
         }
      }, 20);
   }
}
function ToonWaarde(t) {
   document.getElementById("resultaat").innerHTML = t;
}
</script>
<button onclick="Timer(false)">Timer</button>
<p id="resultaat">undefined</p>
 
Nogmaals dank, Bron.
Ik ben bang dat het inderdaad daarop neer gaat komen. Elke functie zijn eigen timeout. Maar ik geef nog niet op. Ik ben nu bezig met een timer die elke itteratie een register aanroept met functies. Functies die afhankelijk zijn van een timer kunnen zich aanmelden. Zolang de functie rendert blijft de timer hem aanroepen en als het renderen klaar is dan meldt de functie zich weer af. Hoe dan ook loopt de timer door. Hoop dat dat gaat werken... Tot nu nog geen succes.
Mochten er meer mensen zijn die tegen dit probleem aanlopen: lets unite our brains!:)

Vriendelijke groet,

Arjan.
 
Breinbrekers hou ik ook van, dat houd je scherp. Ik begrijp dat je de timer meerdere keren nodig hebt en dat deze multifunctioneel moeten zijn. Met objecten werken??

Omdat je scripts wilt laten uitvoeren tijdens het renderen is de volgende code misschien handig. De code geeft een event als het renderen klaar is. De code is niet van mijzelf maar werkt wel erg handig. Het is vergelijkbaar met jQuery $(document).ready() en ik gebruik het om alle scripts vlak boven </body> te zetten om de performance van renderen te verbeteren.
Code:
var DOMReady = function(a,b,c){
  b=document, c='addEventListener';
  b[c] ? b[c]('DOMContentLoaded',a) : window.attachEvent('onload',a)
}
DOMReady(function() {
  .....
});
Noot: DOMContentLoaded is voor moderne browsers en attachEvent is voor oude ie/opera.
 
Hoi Bron,

wat ik probeer te doen is misschien wel helemaal niet mogelijk in js hoor. Ik heb een functie geschreven die elementen opent of sluit in een gegeven aantal seconden. Aangezien het mogelijk is dat een gebruiker in de tijd die nodig is om een element te openen alweer geklikt heeft op een ander element dat geopent of gesloten moet worden moeten er meerdere instanties van dezelfde functie tegelijk kunnen bestaan. Ik kom dus inderdaad uit bij objecten. Jammer genoeg zijn objecten en ik niet echt vriendjes, althans, nog niet...:evil:
Dank voor de code, al snap ik niet eens wat het precies moet doen:o
Ik ga ernaar kijken.

Met vriendelijke groet,

Arjan.
 
In de code van #11 doet dit stukje het volgende
Code:
DOMReady(function() {
  // de code hier wordt pas uitgevoerd [U]nadat[/U] de pagina helemaal klaar is met de opmaak en andere javascript
});
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan