JavaScript - Function returning twice - javascript

I don't know much about JavaScript, here is the code I have:
<script language="JavaScript">
var x = 10
function startClock() {
if (x !== ' ') {
x = x - 1
document.frm.clock.value = x
setTimeout("startClock()", 1000)
}
if (x == 0) {
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
}
}
</script>
<body onLoad(startClock);>
affected iframe:
<input name="clock" size="3" readonly="readonly"
<iframe name="success" src="blank.htm"></iframe>
when the timer counts down, success.php is loaded twice. I know thise because 1.)It inserts data into my DB twice, 2.)I can actually see the loading symbol in the tab reloading a second.
When I change the function to something like:
<script language="JavaScript">
var x = 10
var y = 1
function startClock() {
if (x !== 'Fin') {
x = x - y
document.frm.clock.value = x
setTimeout("startClock()", 1000)
}
if (x == 0) {
x = 'Fin';
document.frm.clock.value = x;
success.location.href = "success.php";
}
}
</script>
...the page is only loaded once.
Can anyone tell me what is happening here? I also tried using '0' in place of ' ' and got the same double execution...

In Javascript there are TWO comparison operators:
"==" -- means equal to
"===" means "exactly equal to" -- which means that the value and the TYPE must be the same
I suspect (although I dind't bother to test the theory) that if you use "===" rather than "==" in your original code you will find it works as you intended. However, there are a number of things that need fixing -- 1) you are inconsistent with using ";", 2) the code should be structured to ensure that on any given iteration it can only "restart" the timer OR fire the sucess and NEVER both. Here is a cleaner version:
<script language="JavaScript">
// 10 iterations at 1 second intervals
var x = 10;
function startClock() {
document.frm.clock.value = --x;
if (x <= 0) {
document.frm.clock.value = x;
success.location.href = "success.php";
} else {
setTimeout("startClock()", 1000);
}
} // startClock
</script>
<body onLoad(startClock);>

First a couple of things. There's a number of "sloppy" coding practices in your example (missing semicolons for instance). While the code may run, it could improve with some jslint help.
So look at the case when x = 1. You decrement x so now x = 0. You then call setTimeout which will wait 1 second and then call your method named startClock. However, setTimeout doesn't block your execution. So immediately after setTimeout is called with x = 0, the code below it is executed where you set x to ' ' (and load your page). Now one second after that code has run, your method is called again due to the timer firing. Since x is now ' ', the top block is skipped and you fall into x == 0 block a second time.

Change it to:
if (x == 0) { // note this is now first
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
} else if (x !== ' ') { // note the else/if
x = x - 1;
document.frm.clock.value = x;
setTimeout("startClock()", 1000)
}
Otherwise, when x is 1, a timeout for startClock() will be set, AND the location will be loaded. Then, the timeout will fire, loading the page again (since x = ' ' and ' ' == 0 returns true).
It is probably better practice to say:
if (x === 0) { // note the ===
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
} else if (x !== ' ') {
x = x - 1;
document.frm.clock.value = x;
setTimeout("startClock()", 1000)
}
Because you don't need the truth conversion that == does for you.
Your example with 'Fin' instead of ' ' worked, because on the startClock() call after the location had been loaded, x was 'Fin', and ('Fin' == 0) is false.

Related

why is the for loop not running?

I'm supposed to create a function that will continue to double the first argument until it is greater than or equal to the 2nd argument. Every time it doubles, I add 20 to a counter.
However, for whatever reason, it doesn't seem to be adding 20 to the counter as it always returns 0 and does not print the console.log I included for each loop, which makes me think it's not running the loop.
Why isn't it running the loop and what am I doing wrong?
function bacteriaTime(currentNum, targetNum) {
let counter = 0
for (let i = currentNum; i >= targetNum; i *= 2) {
counter += 20;
console.log('bacteria count is ' + i + ' and ' + counter + ' have passed.')
}
return counter;
console.log(counter);
}
You might wanna check if your condition wasn't already met, and therefore, the code has returned. Also your condition is backwards. It should be: for (let i = currentNum; i <= targetNum; i *= 2) {
Seems like you've mixed up your comparison. In your for loop you had i >= targetNum which with your inputs would almost always be false. Simply switch the operator to <= as below and you should be good. This will mean i is less than targetNum.
function bacteriaTime (currentNum,targetNum){
let counter = 0
for (let i = currentNum; i <= targetNum; i *= 2){
counter += 20;
console.log ('bacteria count is ' + i + ' and ' + counter+ ' have passed.')
}
console.log(counter);
return counter;
}
Hope that works. It was probably just a simple mix up.

How do I break out of a function in javascript

If I have something like this:
var x = 1;
setInterval(function(){
if (x == "1") {x = "2"};
if (x == "2") {x = "3"};
if (x == "3") {x = "1"};
}, 250);
At the moment, the function runs the first if since it is inherintly true, then since the first if alters x to meet the conditions of the second if, it runs that as well, then does the same with the third and sets x all the way back to 1 How do I get each of the if functions to break out of the setInterval funtion so that after it has ran, the other ifs will not run? I've found how to do this with loops but not for functions. I understand that the above function would probably be better suited in a loop, but it's only an example for the sake of keeping the question short.
Use a ternary expression for this simple case:
var x = 1;
var interval = setInterval(function() {
x < 3 ? x++ : x=1
console.log(x)
}, 250);
// clears the interval after 5000 ms
setTimeout(function() {
clearInterval(interval)
}, 5000);

Having two if condition

I am currently studying if condition statement and it is one of my weakest topic ever. Here in this code below, there are two if conditions and I would like to know, how do we find the output of this? I know how to get the output when there is one if. But what about having two if?
function exercise3(){
var x, y, z;
x = 20;
y = 30;
z = 50;
if ((x - 10) < y) {
if (y - 5 > x) {
alert (z - x);
}
else {
alert (z - 5);
}
}
}
exercise3();
This is referred as Nested If statement. Basically you deal with the most outer block first before the going into the inner block. You would only go into the inner block if the condition in the statement is true.
Your statement condition is true
if ((x - 10) < y) {
...
}
Hence you would proceed to read through.
Take note generally to make it more readable better use If else statements rather than if alone as the execution will proceed to check the next if statement with is actually block one and block two (one by one) bringing about slow execution in long written statements.
Ref: https://www.w3schools.com/js/js_if_else.asp
Cheers, happy learning and happy coding.
That is the same as this, if it helps you understand better. The below snippet is just for example purpose, do not follow that. You need to use nested if conditionals.
function exercise3(){
var x, y, z;
x = 20;
y = 30;
z = 50;
// The first if and nested if from your snippet
if ((x - 10) < y) && (y - 5) > x) {
alert(z - x);
}
// The first if and nested else from your snippet
if ((x - 10) < y && (y - 5) <= x) {
alert (z - 5);
}
}
exercise3();

JavaScript OnClick Method

I was having trouble with the OnClick method I was learning while creating a game. Every time I enter the value and click the button, it is stuck in a loop, I tried document.write and it works using that, but than it opens a new page instead of showing up on screen.
I am new to the programming community, so any help would be nice.
<body>
<p>Enter an integer between 1-100 here:
<input id="number" type="text" />
</p>
<p>
<button onclick="onclickFunction()" type="button">Enter</button>
</p>
<p id="result"></p>
<script type="text/javascript">
function onclickFunction() {
var a = Math.random();
var b = a * 100;
var c = Math.ceil(b);
var intNumber;
var count = 0;
var bool = false;
do {
do {
intNumber = document.getElementById("number").value;
}
while (intNumber > 100 || intNumber < 0);
if (intNumber > c) {
document.getElementById("result").innerHTML = "Too High " + "</br>";
bool = false
} else if (intNumber < c) {
document.getElementById("result").innerHTML = "Too Low " + "</br>";
bool = false
} else if (intNumber == c) {
document.getElementById("result").innerHTML = "You Win!" + "<br>" + " It took you " + count + " tries";
bool = true
}
count = count + 1
} while (bool !== true);
document.getElementById("result").innerHTML = "Win!";
}
</script>
</body>
Updated:
<script type="text/javascript">
// Declare all your functions first
// These functions expect no parameters and return values.
function onclickFunction()
{
var a = Math.random();
var b = a * 100;
var c = Math.floor(b);
// Input from text box.
var randomNumber = document.getElementById("number").value;
// Output to paragraph.
if (randomNumber < c && randomNumber != c)
{
document.getElementById("result").innerHTML = "Too Low " + "</br>";
}
else if (randomNumber > c && randomNumber != c )
{
document.getElementById("result").innerHTML = "Too High" + "</br>";
}
else if (randomNumber == c)
{
document.getElementById("result").innerHTML = "Win!";
}
// Clear text box for further input.
document.getElementById("name").value = "";
}
</script>
<p>Enter an integer between 1-100 here: <input id="number" type="text" /></p>
<p><button onclick="onclickFunction()" type="button">Enter</button></p>
<p id="result"></p>
</body>
First of all, it is always useful to create a fiddle.
That way people who are reading your question can run your code immediately.
Let's break down the code
var a = Math.random();
var b = a * 100;
var c = Math.ceil(b);
This can be done in a single line, to save variables.
do
{
intNumber = document.getElementById("number").value;
}
while (intNumber > 100 || intNumber < 0);
I'm not a big fan of using do/while loops this way, although it can come handy when you want to run the do code at least once, like now.
This loop keeps running when the number is bigger than 100, or smaller than 0. So if I pick an incorrect number that means my browser crashes.
if (intNumber>c){
document.getElementById("result").innerHTML = "Too High " + "</br>";
bool = false
}else if (intNumber<c){
document.getElementById("result").innerHTML = "Too Low " + "</br>";
bool = false
}else if (intNumber == c){
document.getElementById("result").innerHTML = "You Win!" + "<br>" + " It took you " + count + " tries";
bool = true
}
First you are checking if the guess is bigger than the answer, than if it's smaller. That means that the last check if it's equal is unnecessary, since that is the only option left. You can just use an else here.
Also try to be consistent with your spacing and where you place your curly brackets.
do{
//Stuff
}
and
do
{
//Stuff
}
Are both valid ways to use brackets, but stick to one style or your code will get too confusing.
count = count + 1
A small oversight here is that the count starts at 0. So when you guess the number in a single try, it will say you have done it in 0 tries.
while (bool !== true);
document.getElementById("result").innerHTML = "Win!";
}
All the previous code will be done until bool becomes true. The problem here is that if I entered a wrong number (or an invalid number). The program will keep running the if statement which requires a lot of computer power since it never stops. It is impossible to change your guess and the page crashes, because the browser is stuck in the while loop.
The simplest solution for this is to calculate if the new guess was correct when the player inputs a new number. So when onClickFunction is called again.
That way you never have to use a while loop. Although you have to calculate the random number somewhere else.
I hope that helped, if you have any question let me know!

The button doesn't work

<body>
<input id="input"></input>
<button id="button" onclick="evaluate()">Submit</button>
<br>
<p id="id"></p>
</body>
<script>
var a = 1;
var b = 100;
var z = Math.floor(Math.random() * (b-a)) + a;
document.getElementById("id").innerHTML = ("Pick a number between 1 and 100. I will try to guess it. I think it's " + z + ".");
var y = document.getElementById("input").value;
function evaluate() {
var y = document.getElementById("input").value;
if (y == 0) {
a = x + 1;
z = (a+b)/2;
if (z%2==1) {
z = z-0.5
}
document.getElementById("id").innerHTML = ("Now I think it's " + z);
stopEvent();
}
if (y == 2) {
b = x - 1;
z = (a+b)/2;
if (z%2==1) {
z = z-0.5;
}
document.getElementById("id").innerHTML = ("Now I think it's " + z);
stopEvent();
}
if (y == 1) {
document.getElementById("id").innerHTML = ("Yay! I'm so smart.");
stopEvent();
}
}
</script>
When I click on the button it doesn't think of another integer, it does nothing. I can't find any typos. This program is supposed to guess your number in 7 guesses. You think of a number between 1 and 100, and it first chooses a random integer 1-100, then you tell it if it's too high or too low, then it resets its range according to what you told it, and it chooses another integer, and another, until it narrows down to 1 integer.
Your variable x is never defined. You jump right into using x in a calculation when it is undefined. What is x supposed to be? Once you define x everything should work.
a = x + 1; // What is x?
If you do not define x then your function evaluate() will break.
evaluate() is a predefined method available, so change the name of your method name if you see a conflict.
Now as mentioned by mwilson, you are using variable x without declaring it with some value.
I guess you have already defined stopEvent() in your code or else you will get an error there also.

Categories