Cant understand why my onclick does not work - javascript

I am currently studying Javascript and came across a problem while practising setInterval() and `clearInterval().
I am writing a timer that will stop as soon as I press on a button. I have a variable in which I start the interval, a function that executes the timer code and writes the current number the timer is on into a div in HTML.
Then I have a getElementById call that writes an onclick into a button with an id of theButton which contains a clearInterval.
The problem is, if I just write the clearInterval right in the end of the code, without an onclick, it works. But as soon as I write it inside an onclick, it doesn't work without even showing a error.
I have tried searching on the internet and the only answer I got was to use a var instead of a let for the variable with the interval, but that didn't work.
var timerVariable = setInterval(theTimer, 1000);
let count = 11;
function theTimer() {
if (count != 0) {
count--;
document.querySelector("div").innerHTML += count;
console.log("its working");
}
}
document.getElementById("theButton").onclick = 'clearInterval(timerVariable)';

The main reason it doesn't work is because you should assign a function reference to onclick, not a string. Your code should look something like this:
document.getElementById("theButton").onclick = function() {
clearInterval(timerVariable);
});
However, taking this a step further, the onclick is no longer considered good practice. A better solution is to attach your events using addEventListener(), like this:
document.querySelector('#theButton').addEventListener('click', () => {
clearInterval(timerVariable);
});
Here's a full working version with the above correction applied. Note that I added an else case to also clear the interval when the count reaches 0. Without this the interval will run infinitely without any purpose.
var timerVariable = setInterval(theTimer, 1000);
let count = 11;
function theTimer() {
if (count != 0) {
count--;
document.querySelector("div").innerHTML += count;
console.log("its working");
} else {
clearInterval(timerVariable);
}
}
document.querySelector("#theButton").addEventListener('click', () => {
clearInterval(timerVariable);
});
<button type="button" id="theButton">Stop</button>
<div></div>

Related

How to reload a page in javascript while limiting the count of number of times a button is clicked?

What I aiming for is - to reload a page every time the reload button is clicked
(using javascript function : window.location.reload ();) and also keep track of number of times the button (Retake Test) is clicked. The page should reload only for the first three clicks. If the button is clicked more than three times, it should lead to a different page
Code:
<div class = "text-center"> <button type="button" class="btn btn-success
btn-block" onclick ="myCheck();">Retake Test</button>
and here is the solution I came of with (which obviously did not work)
<script>
var count = 0;
function myCheck () {
count = count+1;
if (count < 3) {
window.location.reload();
}
else {
document.write ("YYY");
}
}
</script>
You can try localStorage.
<script>
localStorage.setItem('count', '0');
function myCheck () {
localStorage.setItem('count', +(localStorage.getItem('count'))+ 1)
if (+(localStorage.getItem('count')) < 3) {
window.location.reload();
}
else {
document.write ("YYY");
}
}
</script>
This is a hurried attempt , you can make your code more succinct ofcourse !
ADDITIONAL NOTE: Also avoid using inline javascript like onclick ="myCheck();"
use addEventListener instead.
Since your variables get reset by reloading the page, you maybe want to save count somewhere else. Cookies would be a useful option, in modern browser one could also use local storage.
However maybe the solution you are looking for is reloading only a part of your webpage via AJAX?
Your counts are getting lost on page reload. Use localstorage or cookies
"use strict";
function myCheck() {
var count = localStorage.getItem('count') || 0;
if (count < 3) {
localStorage.setItem('count', (count += 1) )
return window.location.reload();
}
// more than or equal to 3 times
document.write("YYY");
}
Use localStorage.setItem and localStorage.getItem
<script>
var count=typeof localastrorage.getItem('count')!="null"? localstorage.getItem('count'):0;
function myCheck () {
localStorage.setItem("count",count);
count = count+1;
if (count < 3) {
window.location.reload();
}
else {
document.write ("YYY");
}
}
</script>

Run the count down or up function

i wrote a function which do count down or up the numbers to another by pressing a button.
look at this :
var timer;
function counterFn(element,oldCount,newCount,speed) {
if(isNaN(speed)) speed=100;
clearInterval(timer);
if(oldCount===newCount) {
element.text(newCount);
return;
}
var counter=oldCount;
timer=setInterval(function() {
if(oldCount<newCount) {
if(counter>newCount)
clearInterval(timer);
counter++;
} else {
if(counter<newCount)
clearInterval(timer);
counter--;
}
if(counter===newCount) {
clearInterval(timer);
}
element.text(counter);
},speed);
}
$('.button').on("click",function() {
counterFn('.endelement',10,100,1);
});
description of the function attributes:
element : the element which will show the result
oldCount : is the start number
newCount : is the end number
speed : is the repeat time of setInterval
now, according to above code, if you press the element with .button class, counterFn function will run. now if you press the button again (before clearing the setinterval by the function), every thing is OK.
this is the working demo : http://jsfiddle.net/hgh2hgh/gpvn9hcq/4/
as you can see, clicking on the button, clear the previous interval and run the new one.
now if the second element call that function like this :
$('.button2').on("click",function() {
counterFn('.endelement2',50,70,2);
});
naturally the second request will stop the timer and run new timer with the new attributes. cause a global variable is defined for just one setInterval.
look at the comments for demolink of this part : [1] in comments
if definition of the variable be inside the function, pressing the button twice, mean running the function for two separate time.
look at the comments for demolink of this part : [2] in comments
OK, now how to run this function correct?
thanks.

My Javascript timer counting down too fast or it doesn't start onLoad

I have that Javascript counter:
var x=100;
function timerCountdown()
{
document.getElementById('timer1').value=x;
x--;
t=setTimeout("timerCountdown()",1000);
if (x<-1)
{
document.getElementById('timer1').value='Done!';
clearTimeout(t);
}
}
function stopCounter(){
clearTimeout(t);
x=x+1;
}
Then I use:
<body onFocus='timerCountdown()' onBlur='stopCounter()'>
But the problem is, the countdown doesn't start when the page loads. It waits for me to click on another window and to reFocus on the window again.
So I tried this:
<body onLoad='timerCountdown()' onFocus='timerCountdown()' onBlur='stopCounter()'>
But this time, the countdown goes pretty fast. Probably because timerCOuntdown is called twice every second.
Alternatively, I could just use the onFocus and onBlur in the body tag, but I need a function to trigger the Focus upon body load. Is that possible?
Does anyone have a suggestion to solve this problem?
thanks a lot!
The simple answer is because setTimeout is invoked twice, running timerCountdown() once for two times separately, and continually setting two setTimeout IDs.
This would be what you want:
var x = 100;
var t = 0;
function timerCountdown()
{
if (t == 0) t = setInterval(timerCountdown, 1000);
document.getElementById('timer1').value=x;
x--;
if (x < 0)
{
document.getElementById('timer1').value='Done!';
clearTimeout(t);
ticker = 0;
}
}
function stopCounter()
{
clearTimeout(t);
t = 0;
x++;
}
setInterval is much more suited for countdown timers, and things you need to run continually since setTimeout only runs once and you need to keep on calling it.
Edit: This fixes the initial rapid triggering of the timer on Firefox.
Remove the handler from <body onload= and add this to the end of the script block above:
t = setInterval(timerCountdown, 1000);

Other way to "wait" during javascript animation

i'm looking for another way to execute this code :
$.each($("#gallery > img"), function(index,curImg) {
setTimeout(function() {
clearCanvas();
cvsCtx.drawImage(curImg,0,0);
} , index*animationMs);
});
This code draw an image from my gallery to my canvas every animationMs .
But i would like to make it possible to stop the animation, with a "Play/stop" button, I can't do it this way...
Any idea or workaround ?? thank you !!
I can't test it. But you can stop animation by using a variable to hold the setTimeout function as following:
var x; // public var
....
x = setTimeout(......);
// To stop it use:
clearTimeout(x);
Hope this works for you
I find that creating timeouts in a loop is usually too hard to manage - you don't want to have to cancel multiple timeouts. Better to have the function doing the work call itself (indirectly) by setting a timeout just before it completes, because then you can put in a simple if test to decide whether to set the next timeout and continue your animation.
Perhaps a little something like this:
<input id="playPause" type="button" value="Play">
<script>
function initAnimation(animationMs, autoRepeat, waitForPlayButton) {
var currentFrame = 0,
$imgList = $("#gallery > img"),
paused = waitForPlayButton;
function drawNext() {
clearCanvas();
cvsCtx.drawImage($imgList[currentFrame++],0,0);
if (currentFrame >= $imgList.length) {
currentFrame = 0;
if (!autoRepeat) {
paused = true;
$("playPause").prop("value", "Play");
}
}
if (!paused)
setTimeout(drawNext, animationMs);
}
$("playPause").prop("value", waitForPlayButton ? "Play" : "Pause")
.click(function() {
this.value = (paused = !paused) ? "Play" : "Pause";
if (!paused)
drawNext();
});
if (!waitForPlayButton)
drawNext();
}
initAnimation(100, true, false);
</script>
If autoRepeat param is false the animation will run once and stop, but can be restarted via the button, otherwise (obviously) it just keeps repeating.
If waitForPlayButton is false the animation will start immediately, otherwise (obviously) it will start when the button is pressed.
Pressing the button will pause at the current frame.
(Not tested since I don't have a bunch of images handy, but I'm sure you get the idea and can fix any problems yourself. Or let me know if you get errors...)
var images = $("#gallery > img").clone(), interval;
function startLoop() {
interval = setInterval(function(){
var image = images[0];
clearCanvas();
cvsCtx.drawImage(image,0,0);
images.append(image);
}, animationMs);
}
$(".stop").click(function() {clearInterval(interval);});
$(".start").click(startLoop);
setTimeout return a timeoutID which can be given to clearTimeout as a parameter to stop the timeout from happening.
You can read more about this at: https://developer.mozilla.org/en/DOM/window.setTimeout
Good luck
It's not really an animation... but still:
$("#gallery > img").each(function(index,curImg) {
$(this).delay(index*animationMs).queue(function(next) {
clearCanvas();
cvsCtx.drawImage(curImg,0,0);
if (next) next();
});
});
Using jQuery queues like I did allows you to do .stop(true), on $("#gallery > img") or a single image and stop their "animation".
First you could add images to a javascript array variable (eventually global) and then call a function cycle() on that array for all its length.
You should put your setTimeout() call inside that function, assigning it to a variable: var t=setTimeout("cycle()",animationMs); and execute clearTimeout(t); when you want to stop the animation.
Of course you could also save in a variable the frame where you were when stopping the animation and restart exactly from that frame when pressing "play" button.

Using timers (onload)

Ok, firstly, I hardly know Javascript. I really don't know what I'm doing.
So, I have this code:
var interval_id = 0;
var prevent_bust = 0;
// Event handler to catch execution of the busting script.
window.onbeforeunload = function() { prevent_bust++ };
// Continuously monitor whether busting script has fired.
interval_id = setInterval(function() {
if (prevent_bust > 0) { // Yes: it has fired.
prevent_bust -= 2; // Avoid further action.
// Get a 'No Content' status which keeps us on the same page.
window.top.location = 'http://vadremix.com/204.php';
}
}, 1);
function clear ()
{
clearInterval(interval_id);
}
window.onload="setTimeout(clear (), 1000)";
After 1 second I want to clear the interval set earlier. This isn't working. How would I do what I'm trying to do?
If you substitute the last line with window.onload = function() { setTimeout(clear, 1000); }, it should do OK.
There are two errors in your code:
window.onload should be a function, rather than a string ("..."),
setTimeout accepts a function (clear), rather than the result from the function (clear())
By the way, these are some good places to learn JavaScript:
QuirksMode
Mozilla Developer Network

Categories

Resources