2013-02-08 166 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看看馬特的答案。