简体   繁体   中英

JavaScript - Function returning twice

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM