You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将考试正计时系统改为倒计时?附代码求助

考试计时代码改倒计时模式的实现方案

核心逻辑调整

原来的代码是记录并返回用户已用时间,要改成倒计时,只需要把返回值换成总时长 - 已用时间,同时调整前后端的计算和显示逻辑即可。


1. 修改后端 ajax.php 代码

主要调整数据返回逻辑,从返回已用秒数改为剩余秒数,同时修正初始插入的数值:

if(isset($_POST['subId']) && isset($_POST['userId'])){
    $subId = $_POST['subId'];
    $id = $_POST['userId'];
    require_once('../admin/inc/db.php');
    $subQuery = "SELECT * FROM subject WHERE id = '$subId' AND exam = 'on' ";
    $subRun = mysqli_query($con, $subQuery);
    if(mysqli_num_rows($subRun) > 0){
        $subRow = mysqli_fetch_array($subRun);
        $totalTime = $subRow['time']; // 总考试时长(单位:秒)
        $query = "SELECT * FROM timer WHERE user = '$id' AND subject = '$subId' ";
        $run = mysqli_query($con, $query);
        if(mysqli_num_rows($run) == 0){
            // 首次进入考试,已用时间设为0,直接返回总时长作为剩余时间
            $insert = "INSERT INTO timer(user, subject, spent) VALUES('$id', '$subId', 0)";
            $insertRun = mysqli_query($con, $insert);
            echo $totalTime;
        } else{
            $row =  mysqli_fetch_array($run);
            $spent = $row['spent'];
            if($spent < $totalTime){
                $count = $spent + 1;
                $update = "UPDATE timer SET spent = '$count' WHERE user = '$id' AND subject = '$subId' ";
                $updateRun = mysqli_query($con, $update);
                $remainingTime = $totalTime - $count; // 计算剩余时间并返回
                echo $remainingTime;
            } else{
                echo "Time out!";
            }
        }
    } else{
        echo "Time out!";
    }
}

关键修改点:

  • 首次插入数据库时,将spent设为0(原来设为1会导致初始剩余时间少1秒)
  • 返回值从已用时间$count改为剩余时间$totalTime - $count
  • 变量名$time改为$totalTime,更清晰区分总时长和剩余时间

2. 修改前端 timer.js 代码

调整时间格式化逻辑,适配剩余时间的显示:

$(document).ready(function(){
    var subId = $('#subId').val();
    var userId = $('#userId').val();
    var myVar = setInterval(myTimer, 1000);
    function myTimer(){
        $.ajax({
            type: 'POST',
            url: 'inc/ajax.php',
            data: { subId: subId, userId: userId },
            success: function(res) {
                if(res == 'Time out!'){
                    clearInterval(myVar);
                    $('#timer').html('Time over!');
                    $('#exampleModal').modal({
                        backdrop: 'static',
                        keyboard: false
                    });
                } else{
                    var remainingTime = parseInt(res); // 把返回值转为数字,避免字符串计算问题
                    if(remainingTime < 0) remainingTime = 0; // 兜底处理,防止出现负数
                    // 统一格式化分钟和秒,确保两位数显示
                    var min = Math.floor(remainingTime / 60);
                    var sec = remainingTime % 60;
                    var formattedMin = min < 10 ? '0' + min : min;
                    var formattedSec = sec < 10 ? '0' + sec : sec;
                    $('#timer').html(formattedMin + ':' + formattedSec);
                }
            },
            error: function(jqXHR, textStatus, errorThrown){
                if(jqXHR){
                    $('#timer').html('<span class="animated flash infinite">Exam Paused!</span>');
                }
            }
        });
    }
});

关键修改点:

  • 将后端返回的res转为整数,避免字符串类型导致的计算错误
  • 简化时间格式化逻辑,统一处理分钟和秒的两位数显示(比如显示05:03而非5:3)
  • 增加剩余时间小于0时的兜底,避免出现负数计时

额外优化提示

  • 原代码存在SQL注入风险,建议改用预处理语句替换直接拼接SQL,示例:
    $subQuery = "SELECT * FROM subject WHERE id = ? AND exam = 'on' ";
    $stmt = mysqli_prepare($con, $subQuery);
    mysqli_stmt_bind_param($stmt, "i", $subId);
    mysqli_stmt_execute($stmt);
    $subRun = mysqli_stmt_get_result($stmt);
    
  • 可以优化计时逻辑:前端本地维护剩余时间,每秒自减,每5秒同步一次后端数据,既减少AJAX请求频率,又能避免网络波动导致的计时误差

内容的提问来源于stack exchange,提问作者Maitham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:35:14