2013-02-08 55 views
0

我对这里发生的事情感到困惑。测验第一次正常。然而,在第一场比赛之后,我遇到了各种各样的问题。我想单击相同的按钮“#start2”,开始并重新启动测验,即清除计时器,将所有变量恢复为0等,并显示第一个问题。就好像页面已被刷新一般。多次使用setInterval和clearInterval的问题

相反,我越来越快滴答作响,计时器正在增加正确的猜测等等。可怕。

我用modulo来衡量“#start2”div被点击的次数。在第一次点击时,启动计时器。第二次点击 - 我想重置计时器。第三次点击 - 启动计时器,等等。

任何帮助是大规模赞赏。

var n = 0; 
var x = 0; 
var p = 0; 
var incTime; 

function a(n) { 
    var x,y,z; 

    x = Math.floor((Math.random() * 3)) 
    if(x == 0){y = 1; z = 2}else if(x == 1){y = 0; z = 2}else{y = 0; z = 1} 

    $("#question_holder2").text(questions[n].q); 

    $(".answer_holder2").eq(x).text(questions[n].a).data('answer', 'a'); 
    $(".answer_holder2").eq(y).text(questions[n].b).data('answer', 'b'); 
    $(".answer_holder2").eq(z).text(questions[n].c).data('answer', 'c'); 
} 

$(document).ready(function() { 

//timing element 
function startTimer(x){ 
    $("#start2").text(x); 
} 

$("#start2").click(function(){ 
    var setTimer; 
    p++; 
    //if it's been clicked before 
    if(p%2 === 0){ 
     clearInterval(setTimer); 
     $("#start2").text("Start"); 
     n = 0; 
     x = 0; 
     a(n); 
     alert("okay"); 
    }else if(p%2 !== 0){ 
     //never been clicked before 
     a(n); 
     setTimer = setInterval(function(){startTimer(x=x+1)}, 1000); 

     $('.answer_holder2').click(function() { 
      //correct answer given 
      if ($(this).data('answer') === 'a') { 
       n++; 
       if (n < questions.length) { 
        a(n); 
       } else { 
        alert("End of quiz!"); 
        clearInterval(setTimer); 
        $("#start2").text("You took " + x + " seconds, you  answered " + n + "   questions correctly, with - incorrect answers given."); 
        x = 0; 
        n = 0; 
        a(n); 
       } 
      }else{ 
       //incorrect answer given 
       $(this).fadeTo(1000,0.4); 
       var timeString = $("#start2").text(); 
       var incTime = (timeString * 1) + 5; 
       $("#start2").text(incTime); 
       startTimer(incTime); 
       x = incTime; 
      };  
     }); 
    }; 
}); 
}); 
+1

您应该在脚本顶部的变量中定义'setTimer'在全局范围内。 – 2013-02-08 14:39:33

+0

@SeainMalkin其实你不应该在全局范围内定义**任何**。 – freakish 2013-02-08 14:48:26

+1

@freakish这是真的,但由于他已经定义了一堆全局变量,缺乏对范围的一些理解,我决定保持简单。 – 2013-02-08 14:52:20

回答

3

你有这样的:

$("#start2").click(function(){ 
    var setTimer; 
    p++; 
    //if it's been clicked before 
    if(p%2 === 0){ 
     clearInterval(setTimer); 
//.... 

在这种情况下,当你设置为clearInterval线,setTimer始终是0,而不是一个正在运行的定时器的ID。所以这实际上并没有停止任何计时器。如果你不停止计时器,它将继续运行。所以这里的功能:

setTimer = setInterval(function(){startTimer(x=x+1)}, 1000); 

会继续运行。所以下次你创建一个计时器,你现在有两个计时器更新x,它会看起来更快。

试试这个:

$(document).ready(function() { 
    var setTimer; 
    $("#start2").click(function(){ 
     // the rest of your click handler code...  
    }); 

    //timing element 
    function startTimer(x){ 
     $("#start2").text(x); 
    } 
} 

setTimer变量需要的范围存在于您的单击处理程序之外。正如你所做的那样,你每次都声明一个新变量,所以当你尝试清除计时器时,实际上并没有清除计时器。

另外:关于如何重新连接点击处理程序的怪异点也是一个问题。你也需要解决这个问题。

+0

-1:对不起,但您似乎无法理解代码是如何工作的。每次点击“#start2”时它会创建一个新的定时器(这就是为什么它被称为* start *)的原因。我没有看到任何问题。 – freakish 2013-02-08 14:52:08

+0

@freakish:OP有'var setTimer',然后向下几行(在'if'子句中),它们有'clearInterval(setTimer);'。这不起作用。 'setTimer'将始终为0,而​​不是正在运行的计时器。 – 2013-02-08 15:00:08

+0

啊,是的。现在+1。我错过了'clearInterval'这一行。在这种情况下没有多大意义。代码是很长的路要走。 :) – freakish 2013-02-08 15:04:04

1

答案是不好的事情发生,因为这样:

$("#start2").click(function(){ 
    // some code... 
    $('.answer_holder2').click(function() { 
     // some code... 
    }); 
}); 

当你点击#start2新的处理程序连接到.answer_holder2。因此,在例如3次点击之后,.answer_holder2有3个处理程序附加到它上面,当你点击它时,所有3个点火。

你的代码有点复杂,我不会给你一个解决方案如何解决这个问题。但我可以给你一个提示。将内部.click放置在外部.click之外。你可能不得不改变一些代码,但那必须完成。

编辑你可以尝试什么(如快速修复,但不necessarly好)被添加此:

$('.answer_holder2').off("click").click(function() { 

Additonally看看马特的答案。

相关问题