在jquery中为用户设置测试计时器

时间:2014-08-21 13:01:51

标签: jquery html settimeout

我正在尝试为进行测试的用户设置计时器。

计时器从PHP获取一个值,jquery函数用于启动计时器倒计时,直到设定的时间结束。

提交测试表格时:

该函数检查时间是否已经过去,如果是,则提交所有问题和任何可用的答案。否则,它会检查用户是否尝试了所有问题,然后触发提示框,通知用户在最终提交测试表单之前尚未尝试的任何问题。

到目前为止,正在显示为测试设置的时间,但倒计时不起作用,即时间不倒计时。不确定,但可以来自setTimeout()。

这是一个jsfiddle链接

jsfiddle

以下是jquery:

$(document).ready(function(){

    var mins = <?php echo $rw_test['duration']; ?>;
    var secs = mins * 60;
    var currentSeconds = 0;
    var currentMinutes = 0;
    Decrement = function(){

        currentMinutes = Math.floor(secs / 60);
        currentSeconds = secs % 60;
        if(currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
        secs--;
        var htmlVar = currentMinutes + ":" + currentSeconds;
        $('#timerText').html(htmlVar);
        if(secs !== -1) setTimeout(function(){},1000); 
        if(currentSeconds == 00 && currentMinutes==0){

/************** If User time has elapse: Submit form  ****************/

                    document.getElementById('myquiz').submit();                 
                    //document.myquiz.submit();

/************** If User time has elapse: Submit form  ****************/

        }
        else{

/************** User time still yet to elapse and form was submitted by user: check if all questions were answered  ****************/

    $('#myquiz').submit(function(){

        var errors = [];

        $('.content_question').each(function(){

            var answerCont = $(this).next();
            var inputs = $(answerCont).find('input[type=radio], input[type=checkbox]');

            if(inputs.length > 0)
            {
                var groupChecked = false;

                $(inputs).each(function(){
                    if($(this).is(':checked'))
                    {
                        groupChecked = true;
                    }
                });

                if(!groupChecked)
                {
                    errors.push($(this).text().trim());
                }
            }
        });

        if(errors.length > 0)
        {
            var errorMessage = "You forgot to attempt " + errors.length + " questions: \n\n";

            for(var i=0; i<errors.length; i++)
            {
                errorMessage += errors[i] + "\n";
            }
            //alert(errorMessage);
            //return false;
            return confirm(errorMessage+' \n\n Do you want to continue by ending the test?');
        }
    });

/************** User time still yet to elapse and form was submitted by user: check if all questions were answered  ****************/

        }

        };

        setTimeout(Decrement(),1000);   // Initiate timer and begin to Decrement user time till time elapse 

    });

这是html:

<div><span id="timerText"></span> (Remaining test time)</div>

很高兴能得到一些帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

让我先说一下,你不应该依赖JavaScript时间来处理超时敏感的事情。首先,它不准确。即使你可以告诉它每秒运行一次,它也只会尽可能接近每秒运行;只要它在那个一般的时间范围内到达它就有点儿。这是由于JavaScript的性质,我会留给你研究更多。其次,它可以很容易地被一个精明的用户阻止,然后他们就可以根据需要进行测试。您应该确保后端代码还检查他们参加测试的时间(通过检查提供页面和处理提交之间的时间)。

好的,那说你绝对可以用它来帮助用户获得更好的体验。所以我们走了。 JavaScript本质上的小课程。

您尝试的内容似乎采用程序编程风格,这是您在大多数语言中所期望的。您的指示是在您逐行编写时执行的。 JavaScript在某种程度上也是如此,但不是你应该怎么想的。使用JS,您应该以功能样式进行思考。

这意味着你的代码应该都可以很好地封装在彼此处理事件和完成操作时彼此调用的函数中。 setInterval这样做。它会为您检查循环所经过的时间,然后当它看到它在您指定(或经过它)时它会调用您的函数。

我对你的代码采取了一些自由,并清理了一堆并标准化了格式。我发现你的计时器代码令人困惑,所以我几乎完全用一些更简单的东西(simpler is almost always better)取而代之:

// Config
var mins = 5; // Min test time
var secs = 0; // Seconds (In addition to min) test time
var timerDisplay = $('#timerText');

//Globals: 
var timeExpired = false;

// Test time in seconds
var totalTime = secs + (mins * 60);

// This sourced from: http://stackoverflow.com/questions/532553/javascript-countdown
var countDown = function (callback) {
    var interval;
    interval = setInterval(function () {
        if (secs === 0) {
            if (mins === 0) {
                timerDisplay.text('0:00');
                clearInterval(interval);
                callback();
                return;
            } else {
                mins--;
                secs = 60;
            }
        }
        var minute_text;
        if (mins > 0) {
            minute_text = mins;
        } else {
            minute_text = '0';
        }
        var second_text = secs < 10 ? ('0' + secs) : secs;

        timerDisplay.text(minute_text + ':' + second_text);
        secs--;
    }, 1000, timeUp);
};

你会看到我还添加了一个回调函数,该函数在计时器到期时调用。如果在用户提交之前调用此回调,则无论表单是否完成,都应提交表单。如果它是事先提交的,那么您就知道用户提交了它。您可以在此fiddle中看到这一点。 (我包括了漂亮的bootstrap css)

我还纠正了你的大部分HTML。看看,看看你能学到什么。此外,除非您要使用JS为他们做些什么,否则您不需要id。即使这样,最好使用类。

希望它可以帮到你!

答案 1 :(得分:0)

是的,它不是setTimeout,因为它只会在给定时间后执行一次代码。请改用setInterval,它将每隔time秒执行给定的代码:

setInterval(Decrement, 1000);

此外,下次将setTimeoutsetInterval与已在某处定义的函数一起使用时,只需传入函数名称(如上所述)而不是调用函数( Decrement())。 setTimeoutsetInterval会负责调用该功能。