如何修复测验倒计时计时器?代码问题排查与修正求助
测验倒计时计时器问题修复求助
当前问题
- 倒计时卡在第1题,未答题时会自动跳转到下一题
- 答题后无法点击Submit & Next按钮,但页面仍会自动跳题
期望实现效果
- 答题时暂停计时(例如剩余25秒),点击下一题后继续使用剩余时长
- 若用户未答题或超时,弹出“Time is over”提示,禁用当前题选项并自动跳转到下一题
问题代码(quiz.php)
<?php $quiz_questions = $this->crud_model->get_quiz_questions($lesson_details['id']); ?> <div id="quiz-body"> <div class="" id="quiz-header"> <?php echo get_phrase("quiz_title"); ?> : <strong><?php echo $lesson_details['title']; ?></strong><br> <?php echo get_phrase("number_of_questions"); ?> : <strong><?php echo count($quiz_questions->result_array()); ?></strong><br> <?php if (count($quiz_questions->result_array()) > 0): ?> <button id="start_page" type="button" name="button" class="btn btn-sign-up mt-2" style="color: #fff;" onclick="getStarted(1)"><?php echo get_phrase("get_started"); ?></button> <?php endif; ?> </div> <form class="" id="quiz_form" action="" method="post"> <?php if (count($quiz_questions->result_array()) > 0): ?> <?php foreach ($quiz_questions->result_array() as $key => $quiz_question): $options = json_decode($quiz_question['options']); ?> <input type="hidden" name="lesson_id" value="<?php echo $lesson_details['id']; ?>"> <div class="hidden" id = "question-number-<?php echo $key+1; ?>"> <div class="row justify-content-center"> <div class="col-lg-8"> <div class="card text-left"> <div class="card-body"> <h6 class="card-title"><?php echo get_phrase("question").' '.($key+1); ?> : <strong><?php echo $quiz_question['title']; ?></strong></h6> </div> <ul class="list-group list-group-flush"> <?php foreach ($options as $key2 => $option): ?> <li class="list-group-item quiz-options"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="<?php echo $quiz_question['id']; ?>[]" value="<?php echo $key2+1; ?>" id="quiz-id-<?php echo $quiz_question['id']; ?>-option-id-<?php echo $key2+1; ?>" onclick="enableNextButton('<?php echo $quiz_question['id'];?>')"> <label class="form-check-label" for="quiz-id-<?php echo $quiz_question['id']; ?>-option-id-<?php echo $key2+1; ?>"> <?php echo $option; ?> </label> </div> </li> <?php endforeach; ?> </ul> </div> <div class="justify-content-end" style="float: right; margin: 5px 0px 40px 40px;"> <div class="card"> <div class="card-body" id="clock"> <h5 class="text-right m-1"> Quiz Time: 00:<span class="" id="time">00</span></h5> </div> </div> </div> </div> </div> <button type="button" name="button" class="btn btn-sign-up mt-2 mb-2" id="next-btn-<?php echo $quiz_question['id'];?>" style="color: #fff;" <?php if(count($quiz_questions->result_array()) == $key+1):?> onclick="submitQuiz()"<?php else: ?>onclick="showNextQuestion('<?php echo $key+2; ?>')"<?php endif; ?> disabled> <?php echo count($quiz_questions->result_array()) == $key+1 ? get_phrase("check_result") : get_phrase("submit_&_next"); ?></button> </div> <?php endforeach; ?> <?php endif; ?> </form> </div> <div id="quiz-result" class="text-left"> </div> <script type="text/javascript"> // Quiz with Countdown Timer function getStarted(first_quiz_question) { $('#quiz-header').hide(); $('#lesson-summary').hide(); $('#question-number-'+first_quiz_question).show(); var timer = 30; // Time counter var quiz_questionsCount = 0; // Questions counter // Questions array var questions = 'quiz_form'; questionDivId = document.getElementById('start_page'); setInterval(function () { timer--; if (timer >= 0) { id = document.getElementById('time'); id.innerHTML = timer; } if (timer === 0) { id.innerHTML = alert('Time is over. Next Question...'); timer = 30; quiz_questionsCount++; } // To check if all questions are completed or not will be show the quiz result if (quiz_questionsCount === questions.length){ questionDivId.innerHTML = alert('Your time has finally over. It seems some of your quiz has not been answered.'); id.innerHTML = ""; function submitQuiz() { $.ajax({ url: '<?php echo site_url('home/submit_quiz'); ?>', type: 'post', data: $('form#quiz_form').serialize(), success: function(response) { $('#quiz-body').hide(); $('#quiz-result').html(response); } }); } } else{ questionDivId.innerHTML = questions[quiz_questionsCount]; } }, 1000) // To go to the next question function showNextQuestion(next_question) { $('#question-number-'+(next_question-1)).show(); $('#question-number-'+next_question).show(); quiz_questionsCount++; timer = 30; } } function submitQuiz() { $.ajax({ url: '<?php echo site_url('home/submit_quiz'); ?>', type: 'post', data: $('form#quiz_form').serialize(), success: function(response) { $('#quiz-body').hide(); $('#quiz-result').html(response); } }); } function enableNextButton(quizID) { $('#next-btn-'+quizID).prop('disabled', false); } </script>
需修正的代码位置与问题说明
1. 计时器核心逻辑错误(getStarted函数内)
- 变量赋值错误:
var questions = 'quiz_form';把字符串当成题目数组,导致questions.length永远是9,和实际题目数量不匹配;questionDivId = document.getElementById('start_page');错误绑定到开始按钮,而非题目容器,切换逻辑完全失效。 - setInterval未做管理:没有保存interval的ID,无法暂停/清除计时器,导致答题时计时不会停止,自动跳题不受控制。
- 超时逻辑缺失:计时器到0时仅弹出alert,没有禁用当前题选项、隐藏当前题并显示下一题的实际操作。
2. 题目切换逻辑错误(showNextQuestion函数)
- 函数内错误执行
$('#question-number-'+(next_question-1)).show();,没有隐藏上一题,导致所有题目叠加显示,视觉上卡在第1题。 - 切换题目时强制重置计时器为30秒,没有保留剩余时长,不符合需求。
3. 按钮交互与计时暂停逻辑缺失
enableNextButton函数仅启用按钮,但没有暂停计时器;同时页面自动跳题是因为setInterval一直在后台运行,没有在用户答题时暂停。- 按钮的
onclick事件绑定的showNextQuestion参数正确,但函数本身逻辑错误,导致点击后无法正常切换题目。
4. 重复定义submitQuiz函数
- 在
getStarted的setInterval内又定义了一次submitQuiz,覆盖了全局的submitQuiz函数,导致按钮点击提交可能失效。
关键修正方向示例
- 全局管理计时器变量与interval ID:
let timer = 30; let quiz_questionsCount = 0; let intervalId; const totalQuestions = <?php echo count($quiz_questions->result_array()); ?>;
- 答题时暂停计时器,切换时恢复:
function enableNextButton(quizID) { $('#next-btn-'+quizID).prop('disabled', false); clearInterval(intervalId); // 暂停计时 } function showNextQuestion(next_question) { $('#question-number-'+(next_question-1)).hide(); $('#question-number-'+next_question).show(); quiz_questionsCount++; // 恢复计时,不重置时长 intervalId = setInterval(timerTick, 1000); }
- 完善超时逻辑:
function timerTick() { timer--; document.getElementById('time').innerHTML = timer.toString().padStart(2, '0'); if (timer === 0) { alert('Time is over. Next Question...'); // 禁用当前题所有选项 $('#question-number-'+(quiz_questionsCount+1) + ' .form-check-input').prop('disabled', true); // 自动切换下一题 if (quiz_questionsCount +1 < totalQuestions) { showNextQuestion(quiz_questionsCount +2); } else { submitQuiz(); } } }
内容的提问来源于stack exchange,提问作者Blake Resurreccion
相关产品推荐
相关产品推荐

