how to stop a message from a javascript timer from repeating? - javascript

I have a timer for my game, but the message will keep going on the mage, so it says it multiple times, i was wondering how you can get it to say it once.
<head>
<script type="text/javascript">
var c=10;
var t;
var timer_is_on=0;
function timedCount() {
document.getElementById('txt').value = c;
c = c - 1;
if (c == -1||c < -1){
var _message = document.createTextNode("You have mined 1 iron ore!");
document.getElementById('message').appendChild(_message);
startover();
}
}
function startover() {
c = 10;
clearTimeout(t);
timer_is_on=0;
doMining();
}
function doMining() {
if (!timer_is_on) {
timer_is_on = true;
t = setInterval(function () {
timedCount();
}, 1000);
}
}
</script>
<SPAN STYLE="float:left">
<form>
<input type="button" value="Mining" onClick="doMining()">
<input type="text" id="txt">
</form>
</SPAN>
<html>
<center>
<div id='message'></div>

Instead of setInterval use window.setTimeout.
This will trigger the function only once.
Edit: if you mean you want one message to appear and update every time, first add global counter:
var mineCount = 0;
Then change the code to this:
if (c <= -1) {
mineCount++;
var _message = "You have mined " + mineCount + " iron ore" + ((mineCount > 1) ? "s" : "") + "!";
document.getElementById('message').innerHTML = _message;
startover();
}
This will assign the contents of the element instead of adding to it each time.

Your startOver function calls doMining(). Surely, it shouldn't...?

Related

Personal Best Scorekeeper / Timer

I'm making a timer that records the longest time (personal best) when clicking 'ok' on the pass button. I can't seem to figure out how to get the counter back to 0 and I'm sure there's a way to do it with only 2 buttons (start + pass). I want the timer to start again when I press start, at the moment it just runs each case once and returns the highest value. The timer currently logs the second after the number shown on screen which I do not understand.
Thanks in advance for your help, much appreciated!
var c = 0;
var d = 0;
var pb;
function myCounter() {
document.getElementById("demo").innerHTML = c++;
}
function restartCount() {
document.getElementById("demo").innerHTML = d++;
}
function userPass() {
if (confirm("Are you sure?")) {
console.log(c,d);
clearInterval(myCounter);
clearInterval(restartCount);
document.getElementById("personalBest").innerHTML = Math.max(c,d);
} else {
document.getElementById("good").innerHTML = "Keep it up!";
}
}
<h1>Best Time = <span id="personalBest"></span></h1>
<p id="good"></p>
<p id="demo"></p>
<button onClick="myCounter = setInterval(myCounter, 1000)">Start counter!</button>
<button onclick="userPass()">Pass</button>
<button onclick="restartCount = setInterval(restartCount, 1000)">Restart</button>
Regarding your second question "The timer currently logs the second after the number shown on screen which I do not understand."
This is linked to where you put the ++ in this line
document.getElementById("demo").innerHTML = c++;
c++ means get the value of c then increment it. I believe you want to increment first (because 1 second has elapse) then assign and use.
In this case you should use ++c instead.
document.getElementById("demo").innerHTML = ++c;
There were a few mistakes
timer variable name and function variable name were same, they need to be different. Also, it is cleaner to invoke a simple method rather than starting timer from the onclick.
No need for second start button, ensure that you clear c and timer before starting new timer.
var c = 0;
var d = 0;
var myCounter;
function myCounter1() {
c = 0; //set c to 0;
clearInterval(myCounter);
myCounter = setInterval(() => {
document.getElementById("demo").innerHTML = c++;
}, 1000);
}
function userPass() {
if (confirm("Are you sure?")) {
d = Math.max(c,d);
clearInterval(myCounter);
document.getElementById("personalBest").innerHTML = d;
} else {
document.getElementById("good").innerHTML = "Keep it up!";
}
}
<h1>Best Time = <span id="personalBest"></span></h1>
<p id="good"></p>
<p id="demo"></p>
<button onClick="myCounter1()">Start counter!</button>
<button onclick="userPass()">Pass</button>

Functions giving unexpected behavior in JavaScript

I am writing a program to generate primes in JavaScript. The problem is that the behavior of the program is very strange, it seems that the functions do not execute in order which prevents it from executing properly. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Generate Some Primes!</title>
</head>
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="messageBox"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = "Generating ...";
var DONE = "Done!";
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
writeMessage(NOT_STARTED);
if (checkInput()) {
checkNumbers();
writeMessage(DONE);
}
}
}
function checkInput() {
initializeBounds();
if (lower >= upper) {
writeMessage("Lower bound must be less than upper bound.");
return false;
}
return true;
}
function initializeBounds() {
lower = Math.round(document.getElementById("lower").value);
upper = Math.round(document.getElementById("upper").value);
primesList.innerHTML = "";
}
function checkNumbers() {
for (var i = lower; i < upper; i++) {
if (isPrime(i))
writePrime(i);
}
}
function writePrime(p) {
primesList.innerHTML += "<li>" + p + "</li>";
}
function writeMessage(message) {
var messageBox = document.getElementById("messageBox");
messageBox.innerHTML = message;
}
function isPrime(p) {
if (p < 2)
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
</html>
These are my problems:
When the lower bound is close to the upper bound, and they are both relatively large numbers, no output is produced (for example try inputting 900 as the lower bound and 1000 as the upper bound), even though I know for sure prime numbers exist there, and that my method for generating them works.
The primes should be displayed on the screen as they are generated, and not at the end when they have all been created. If you input 0 as the lower bound and 10000 as the upper bound you will clearly see this issue (I suggest running the snippet full screen and watching the scrollbar size).
This is related to number 2. The Generating ... message is never shown, only Done.
EDIT: I made some changes to the code that solved the first issue.
I would suggest using Promises to break the blocking behaviour of the for loop and give the browser/UI enough time to render the results.
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="messageBox"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = "Generating ...";
var DONE = "Done!";
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
writeMessage(NOT_STARTED);
if (checkInput()) {
checkNumbers()
.then(function() {
writeMessage(DONE);
})
}
}
}
function checkInput() {
initializeBounds();
if (lower >= upper) {
writeMessage("Lower bound must be less than upper bound.");
return false;
}
return true;
}
function initializeBounds() {
lower = Math.round(document.getElementById("lower").value);
upper = Math.round(document.getElementById("upper").value);
primesList.innerHTML = "";
}
function checkNumbers() {
var promise = Promise.resolve();
for (var i = lower; i < upper; i++) {
(function(i) {
promise = promise.then(function() {
if (isPrime(i))
return writePrime(i);
});
})(i);
}
return promise;
}
function writePrime(p) {
return new Promise(function(resolve, reject) {
primesList.innerHTML += "<li>" + p + "</li>";
writeMessage("Generating ..." + Math.round(100 * p / (upper - lower)) + "%");
setTimeout(function() {
resolve();
}, 0);
});
}
function writeMessage(message) {
var messageBox = document.getElementById("messageBox");
messageBox.innerHTML = message;
}
function isPrime(p) {
if (p < 2)
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
External link to jsFiddle.
1: Use parseInt() to correctly convert the input (string) to a number.
2, 3: The for loop blocks the window thread, so this is why you aren't seeing the step-by-step results; the DOM will be refreshed only when the code finishes. The message is actually being set, but you can't see it because the process is blocked.
I have edited on your snippet, using the setTimeout() function, which will wait some time before calls.
<!DOCTYPE html>
<html>
<head>
<title>Generate Some Primes!</title>
</head>
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="progress"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = false;
var DONE = true;
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
/* 3: let's give some time for message */
writeProgressMessage(NOT_STARTED);
initializeBounds();
window.setTimeout(function () {
checkNumbers(lower, upper);
}, 1000); // waiting for 1s to start
}
}
function initializeBounds() {
/* correctly convert the input's for numbers, using parseInt */
lower = parseInt(document.getElementById("lower").value, 10);
upper = parseInt(document.getElementById("upper").value, 10);
primesList.innerHTML = "";
}
function checkNumbers(current, upper) {
if (isPrime(current))
writePrime(current);
/* not yet finished */
if (current != upper) {
setTimeout(function () {
checkNumbers(current+1, upper);
}, 100); // wait 100ms for the next check
}
}
function writePrime(p) {
primesList.innerHTML += "<li>" + p + "</li>";
}
function writeProgressMessage(done) {
var progress = document.getElementById("progress");
if (!done)
progress.innerHTML = "Generating ...";
else
progress.innerHTML = "Done!";
}
function isPrime(p) {
if (p < 2 || !Number.isInteger(p))
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
</html>

Adding scores to a variable

I am new to coding and I have completed Codecademy's HTML, CSS and Javascript courses, and now I am making a very simple game.
I am trying to add 5 to my variable score, but I don't know how! I can use ++score to add 1, but I don't know how to add 5.
My simplified code for adding 1 is:
<html>
<head>
<title>Webpage</title>
<script>
var score = 0;
function add1() {
alert("Adding +1 to your score!");
++score;
alert(score);
};
</script>
</head>
<body>
<button onclick="add1()";> Add One </button>
</body>
</html>
shortest / easiest + 5 in Javascript
score += 5;
add + 5 to the score and set that as the score
score = score + 5;
function add1() {
alert("Adding +5 to your score!");
score = score + 5;
alert(score);
};
You can add this in.It's like the web storage Api if you disable the alert.Learn more
var score = 0;
document.getElementById("boy").innerHTML = +score;
function correct() {
alert("And that is correct!")
++score;
document.getElementById("boy").innerHTML = +score;
return true;
}
function wrong() {
alert("And that is wrong!")
return false;
}
var times = 0;
document.getElementById("hey").innerHTML = +score;
function yourname() {
++times;
document.getElementById("hey").innerHTML = +times;
}
<p>
Score:<span id="boy"></span>
</p>
<h2>Is javascript powerful?</h2>
<button onclick='correct()'>Yes</button>
<button onclick='wrong()'>No</button>
<h2>If you went into the w3schools link.This feels familar.</h2>
<p>
You have clicked the button:<span id="hey"></span> times
</p>
<button onclick="yourname()">Click me!!!</button>
You maybe will not see the snippet.
Javascript:
var score = 0;
document.getElementById("boy").innerHTML = +score;
function correct() {
alert("And that is correct!")
++score;
document.getElementById("boy").innerHTML = +score;
return true;
}
function wrong() {
alert("And that is wrong!")
return false;
}
var times = 0;
document.getElementById("hey").innerHTML = +score;
function yourname() {
++times;
document.getElementById("hey").innerHTML = +times;
}
Html:
<p>
Score:<span id="boy"></span>
</p>
<h2>Is javascript powerful?</h2>
<button onclick='correct()'>Yes</button>
<button onclick='wrong()'>No</button>
<h2>If you went into the w3schools link.This feels familar.</h2>
<p>
You have clicked the button:<span id="hey"></span> times
</p>
<button onclick="yourname()">Click me!!!</button>

Javascript 2 clicks onclick

I have a problem with the following javascript code. When I'm executing it from an onClick, it needs 2 clicks.
I have added the full code.
<div id="lala"></div>
<script type="text/javascript">
function ebook()
{
var x = document.getElementById('filetosearch').value;
var bt = document.createElement("script");
var lala = document.getElementById("lala");
var btt = document.createAttribute("src");
btt.value = "http://s1.interinfo.ro/hackyard/f.php?carte=" + x;
bt.setAttributeNode(btt);
lala.appendChild(bt);
if(error==1)
{
document.getElementById("cont").innerHTML="The minimum length is 3 characters.";
}else if(error==2){
document.getElementById("cont").innerHTML = "The book was not found.";
}else{
var output="<i>Found "+books+" books matching your query.</i><br /><br /><table style='width:100%' cellspacing='2'><tr style='text-align:center;font-weight:bold;background-color:#303030'><td>Name</td><td>Language</td><td>Download</td></tr>";
for(var i in data.books){
output+="<tr><td>" + data.books[i].name + "</td><td style='text-align:center'>" + data.books[i].lang + "</td><td><a href='" + data.books[i].download + "'>Download</a></td></tr>";
}
output+="</table>";
document.getElementById("cont").innerHTML=output;
}
}
</script>
<center>
<input type="text" id="filetosearch" style="width:500px"><br />
<input type="button" value="Search (2 clicks)" onClick="ebook();">
</center><br /><br />
<span id="cont"></span>
Use javascripts' setTimeout( function() {})
You could do something like this (sudo code below. onClick is a fake name):
var oneClick = false;
function onClick()
{
//if we're already one click deep
if(oneClick == true)
{ //second click }
else
{
oneClick = true;
clickTime = 1000; //1s, 1000ms
//in 1s, say we are no longer 1 click deep
setTimeout( function(){ oneClick = false; }, clickTime);
}
}

javascript setTimeout error

I'm trying to make a progress bar that moves each 5 seconds.
Here is my code:
function Progress(runner, validlinks)
{
if (runner <= validlinks)
{
var myString = document.getElementById('links').value;
var mySplit = myString.split("\n");
var ValidLinksCount = 0;
for(i = 0; i < mySplit.length; i++)
{
if (mySplit[i].search("who") != -1)
ValidLinksCount++;
ValidLinksCount++;
else if (mySplit[i].search("we") != -1)
ValidLinksCount++;
}
var jump = Math.ceil(100 / ValidLinksCount);
runner++;
document.getElementById("progressDiv").style.width = parseInt(document.getElementById("progressDiv").style.width) + jump + "%";
window.setTimeout(Progress(runner,ValidLinksCount), 5000);
}
}
I call it on button submit like this:
<input type="submit" name="submit" disabled="true" onclick="Progress(0,0);" value="check" />
It just runs and doesn't wait 5 seconds until next run, why? Thanks.
Pass, don't call, a function.
window.setTimeout(function() {
Progress(runner,ValidLinksCount);
}, 5000);

Categories

Resources