2012-01-11 68 views
1

我不知道太多关于JavaScript的,这里是我的代码:JavaScript的 - 函数返回两次

<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);> 

受影响的iframe:

<input name="clock" size="3" readonly="readonly" 

<iframe name="success" src="blank.htm"></iframe> 

当定时器倒计时,success.php被加载两次。我知道这是因为1)它将数据插入我的数据库两次,2)我实际上可以看到加载符号在标签重新加载一秒钟。

当我改变函数是这样的:

<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> 

...页面只装载一次。

谁能告诉我这里发生了什么?我使用的地方“”“0”也试过,得到了相同的双执行...

+0

改变你的第二个'if'和'else if'可能会解决你的问题。 – Ivan 2012-01-11 23:20:47

+0

*“它将数据插入我的数据库两次。”*然后您可能需要修复您的服务器页面。 “GET”操作必须是[幂等](http://en.wikipedia.org/wiki/Idempotence)(抱歉,不是我的话)。对于*改变事物的操作,使用'POST'或其他动词之一。 (在我看来,例外是“访问”数据。) – 2012-01-11 23:22:34

+0

问题的第一个版本使用了标志值'“”'。当前版本使用'“Fin”'。这是什么?哦,等一下,它又回到''“''。 – 2012-01-11 23:23:29

回答

0

将其更改为:

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) 
} 

否则,当x 1,用于startClock超时()将被设置,并且该位置将被加载。然后,超时将触发,再次加载页面(因为x = ' '' ' == 0返回true)。

这可能是更好的做法,说:

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) 
} 

因为你不需要真相转换是==为你做。


您与'Fin'代替' '例如工作,因为该位置已经被加载后startClock()电话,x'Fin'('Fin' == 0)是假的。

+0

刚试过,出于某种原因,else if语句没有被运行......定时器在到达零点后继续进入负值。这就好像x从不等于0 – user1142872 2012-01-11 23:46:54

+0

啊。逻辑错误。我会更新答案 - 但我会推荐@Murray麦当劳的版本。他更清洁。我给了他一个upvote - 如果你发现他的解决方案也有用,你也应该:)(也欢迎Stack Overflow) – 2012-01-11 23:53:43

+0

现在应该修复。 – 2012-01-11 23:56:22

0

首先几件事。在你的例子中有很多“马虎”的编码习惯(例如缺少分号)。尽管代码可能会运行,但可以通过一些jslint帮助来改进。

所以看看x = 1的情况。现在x递减,现在x = 0。然后调用setTimeout,它将等待1秒钟,然后调用名为startClock的方法。但是,setTimeout不会阻止您的执行。所以在setTimeout被x = 0调用之后,下面的代码会在你设置x为''(并加载你的页面)的地方执行。现在代码运行一秒后,由于定时器触发,您的方法会再次被调用。由于x现在是'',所以上面的块会被跳过,并且你第二次陷入x == 0块。

1

在Javascript中有两个比较操作符:

“==” - 意味着等于

“===”是指“完全等于” - 这意味着值和TYPE必须是相同的

我怀疑(尽管我不费心去测试理论),如果您在原始代码中使用“===”而不是“==”,您会发现它可以按照您的预期工作。然而,还有一些需要解决的问题 - 1)您与使用“;”不一致,2)代码的结构应确保在任何给定的迭代中,只能“重新启动”计时器或触发成功从来没有。这里是一个更清洁的版本:

<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);> 
+0

+1很好的答案。我认为第二个'document.frm.clock.value = x;'是多余的。或者你的意思是'='';'? – 2012-01-11 23:59:52

+0

是的,完全是多余的 - 只是被忽略,因为我正在移动的东西 - 在PHP 0 ==''是真,但0 ===''是假 - 我知道上面引用的代码是使用''(单空白而不是空字符串),但事实上,当他从“Fin”改变他的“定点”价值时,它非常有效地让我认为这就是发生了什么 – 2012-01-12 00:05:24

+0

感谢您清理'=='和'== ='操作员,学到了新东西。感谢您的干净的代码,很好用! – user1142872 2012-01-12 00:05:40