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);>
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.