ming ming - 7 months ago 12
Javascript Question

how to stop the accumulation while using setTimeout()?

.js

<script type="text/javascript">
var c={{ rest_time }}
var t

function timedCount()
{
if(c>-1){
$('#txt').html(c)
c=c-1
t=setTimeout("timedCount()",1000) //1000ms后,执行参数1(调用自身)
}

else{
$('#txt').html("time's up")
}
}
$(document).ready(timedCount())

</script>


django view

def show_reply_page(request, topic_id):
t = topic.objects.get(id=topic_id)
comments = t.comment_set.filter(deleted=False)
posts = t.post_set.filter(deleted=False)
past_time = int(time.time() - t.locktime)
rest_time = 300 - past_time
t.save()
return render_to_response('forum/reply.html', {'conf': conf, 'title': t.title,
'request': request,
'topic': t,
'posts': posts,
'comments': comments,
'past_time': past_time,
'rest_time' : rest_time,
},
context_instance=RequestContext(request))


when I click the button, the django view will give a {{rest_time}} to the javascript. Then it would do the countdown( every second timedCount() calls itself ). But when I click it again, the speed of countdown accumulate. It means when I click it ten times, it counts 10s per second. How to correct this problem?

Answer

Two options:

Option 1: Set a global value in the beginning of your function. For example window.counterStarted.

But even before you set that value, check if that global value is already set. If so, then don't start it again.

if(typeof window.counterStarted !== undefined){
    return false;
}
window.counterStarted = true;

Option 2: Define setTimeout to a global value like window.myTimeout instead of the local variable t within the function. Then to clear the previous timeout before the new one starts, use the following in the beginning of your function:

if(typeof window.myTimeout !== undefined){
    clearTimeout(window.myTimeout);
}