javascript 计时器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5767022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript timer
提问by query
I am trying to make the following javascript timer perform two functions with a click of one button only - click once the timer starts; click again; it stops. click a third time it starts again, and so forth. What am I doing wrong in here? Thank you very much in advance.
我正在尝试使以下 javascript 计时器仅通过单击一个按钮即可执行两个功能 - 计时器启动后单击;再次点击;它停止。第三次单击它会再次启动,依此类推。我在这里做错了什么?非常感谢您提前。
<html>
<head>
<script type="text/javascript">
var c=0;
var t;
var timer_is_on=0;
function timedCount()
{
document.getElementById('txt').value=c;
c=c+1;
t=setTimeout("timedCount()",1000);
}
function doTimer()
{
if (!timer_is_on)
{
timer_is_on=1;
timedCount();
}
}
function stopCount()
{
clearTimeout(t);
timer_is_on=0;
}
function both(){
doTimer();
stopCount();
}
</script>
</head>
<body>
<form>
<input type="button" value="Start count!" onclick="doTimer" />
<input type="text" id="txt" />
<input type="button" value="Stop count!" onclick="stopCount()" />
</form>
<p>
Click on the "Start count!" button above to start the timer. The input field will count forever, starting at 0. Click on the "Stop count!" button to stop the counting. Click on the "Start count!" button to start the timer again.
</p>
</body>
</html>
回答by Weston C
You don't describe an actual problem, so I'm not quite sure what to respond with, but here's a couple of potentially helpful notes.
您没有描述实际问题,所以我不太确定要回答什么,但这里有一些可能有用的说明。
The timedCount function is quasi-timed-recursive. This is cool if you're into continuation passing style, but it's not necessary, probably a little more confusing than it needs to be for JavaScript, and will waste some resources (stack frames) in languages that don't have tail-recursive stack cleanups (don't know if JS has that or not).
timedCount 函数是准定时递归的。如果你喜欢延续传递风格,这很酷,但它不是必需的,可能比 JavaScript 需要的更令人困惑,并且会在没有尾递归堆栈的语言中浪费一些资源(堆栈帧)清理(不知道 JS 是否有)。
Since this is a repeating function execution, you could use setInterval
instead of setTimeout
, and have a single repeated function call that checks to see if it should increment and re-display the count... something like this:
由于这是一个重复的函数执行,您可以使用setInterval
而不是setTimeout
,并有一个重复的函数调用来检查它是否应该增加并重新显示计数......像这样:
var c=0;
var timer_is_on=false;
function displayCount() {
document.getElementById('txt').value=c;
}
function count() {
if(timer_is_on) {
c=c+1;
displayCount();
}
}
var interval = setInterval(count,1000);
Now, to address the single-button part of the problem. Let's say there's a single button:
现在,解决单键部分的问题。假设有一个按钮:
<input type="button" value="Start count!" onclick="toggle" />
When we click on it, we want that "value" attribute to change, and we want it to flip the timer_is_on
variable. Let's create a function that does all these things:
当我们点击它时,我们希望“值”属性发生变化,我们希望它翻转timer_is_on
变量。让我们创建一个函数来完成所有这些事情:
function toggle() {
if(timer_is_on) {
timer_is_on = false;
this.value = "Start count!"; // `toggle` is invoked by the button's event handler, so `this` is the button
} else {
timer_is_on = true;
this.value = "Stop count!";
}
}
So... count is always executing every 1000ms, but it only does anything if timer_is_on, and whether or not timer_is_on is true or false is controlled by toggle
, which is attached to our button. Little bit simpler, I think.
所以... count 总是每 1000 毫秒执行一次,但它只在 timer_is_on 时执行任何操作,并且 timer_is_on 是真还是假由 控制toggle
,它附加到我们的按钮上。稍微简单一点,我想。
UPDATE
更新
What if we wanted to nothave the function count
always running in the background? As Tom Tu points out, this may represent a CPU overhead. I'm not certain it's a measurable one (or that it represents any overhead beyond the timer the browser is probably running to do its own UI updates), but it could be important on some platforms and so it's probably worth addressing.
如果我们想不具备的功能count
一直在后台运行?正如 Tom Tu 指出的那样,这可能代表 CPU 开销。我不确定这是一个可衡量的(或者它代表浏览器可能运行的计时器之外的任何开销来执行自己的 UI 更新),但它在某些平台上可能很重要,因此它可能值得解决。
While we're polishing, I don't much like attaching event handlers through tag attributes myself, or putting variables in the global/window scope if I can avoid it, so I'd probably wrap all our relevant counter setup/processing JavaScript inside one big setupCounter
function, and also attach the toggle
function to the onclick
event of the input button using DOM selection and JavaScript. I'd probably try to only run the document.getElementById
lookups once each, too.
在我们完善时,我不太喜欢自己通过标签属性附加事件处理程序,或者如果可以避免的话,将变量放在全局/窗口范围内,所以我可能会将所有相关的计数器设置/处理 JavaScript 包装在里面一个大setupCounter
函数,并且还使用 DOM 选择和 JavaScript将该toggle
函数附加到onclick
输入按钮的事件。我也可能会尝试只运行document.getElementById
一次查找。
So, let's say the button input has the id startstop
but otherwise assume similar markup. I'd probably do something like this:
因此,假设按钮输入具有 id,startstop
但其他情况下采用类似的标记。我可能会做这样的事情:
function setupCounter() {
var c=0,
interval,
counter_display = document.getElementById('txt'),
button = document.getElementById('startstop');
function display_count() {
counter_display.value = c;
}
function count() {
c=c+1;
display_count();
}
function toggle() {
if(!interval)
interval = setInterval(count,1000);
button.value = "Stop count!";
else {
clearInterval(interval);
interval = false;
button.value = "Start count!";
}
}
button.onclick = toggle;
}
Then you'd call setupCounter
either sometime in the document after both the counter_display and startstop elements have been declared, or assign it to the window.onload
event or pass it to something like jQuery's $(document).ready()
.
然后,您setupCounter
可以在声明 counter_display 和 startstop 元素后在文档中的某个时间调用,或者将其分配给window.onload
事件或将其传递给类似 jQuery 的$(document).ready()
.
回答by kamal
Try this
尝试这个
<form name="f1">
<input type="text" id="but" />
<input type="button" value="start" onclick="timer()" />
<input type="button" value="stop" onclick="stoptimer()" />
</form>
<script type="text/javascript">
var count=0;
var x;
function timer(){
x=setTimeout("timer()",1000);
count=count+1;
document.getElementById("but").value=count;
}
function stoptimer(){
clearTimeout(x);
}
</script>
回答by Sergio Morstabilini
you forgot the brackets after doTimer:
你忘记了 doTimer 后的括号:
<input type="button" value="Start count!" onclick="doTimer" />
回答by Cheeso
Try this code:
试试这个代码:
var c=0;
var t;
var timer_is_on= false;
function timedCount() {
document.getElementById('txt').value=c;
c++;
if (timer_is_on) {
t= setTimeout(timedCount,1000);
}
}
function doTimer() {
if (!timer_is_on) {
timer_is_on=true;
timedCount();
}
else {
clearTimeout(t);
timer_is_on=false;
}
}
Attach the doTimer()
fn to each of your buttons.
将doTimer()
fn附加到每个按钮上。
Example: http://jsbin.com/onoge4/3
Changes I made: use true/false instead of 1/0.
我所做的更改:使用 true/false 而不是 1/0。
回答by no.good.at.coding
The JavaScript
Note the use oftrue
andfalse
instead of1
and0
.var timer_is_on=false; //.. function doTimer() { if (!timer_is_on) { timer_is_on=true; timedCount(); } else { timer_is_on=false; stopCount(); } }
The HTML
I see your button is already set to calldoTimer()
onclick
(however, note that you're missing the parentheses):<input type="button" value="Start count!" onclick="doTimer()" />
Changing the text of the button
First, assign anid
to the button:<input type="button" id="toggleTimer" value="Start count!" onclick="doTimer()" />
Next, modify the JS:
function doTimer() { if (!timer_is_on) { timer_is_on=true; document.getElementById("toggleTimer").value="Stop count!"; timedCount(); } else { timer_is_on=false; document.getElementById("toggleTimer").value="Start count!"; stopCount(); } }
JavaScript
注意使用true
andfalse
代替1
and0
。var timer_is_on=false; //.. function doTimer() { if (!timer_is_on) { timer_is_on=true; timedCount(); } else { timer_is_on=false; stopCount(); } }
我看到您的按钮的 HTML已设置为调用doTimer()
onclick
(但是,请注意您缺少括号):<input type="button" value="Start count!" onclick="doTimer()" />
更改按钮的文本
首先,为按钮分配一个id
:<input type="button" id="toggleTimer" value="Start count!" onclick="doTimer()" />
接下来修改JS:
function doTimer() { if (!timer_is_on) { timer_is_on=true; document.getElementById("toggleTimer").value="Stop count!"; timedCount(); } else { timer_is_on=false; document.getElementById("toggleTimer").value="Start count!"; stopCount(); } }