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

Django测验应用中type='submit'按钮的OnSubmit函数失效

Django测验应用提交按钮无弹窗直接刷新问题排查与修复

问题描述

我用Django开发一款测验应用,这是首次使用Django。目前其他功能正常,但点击提交答案按钮时,页面直接刷新,无法触发预期的提示弹窗。

我的HTML代码

<section>
    <div id="results"></div>
    <form name="quizForm" onsubmit="return submitAnswers(answers = [{% for q in questions%}'{{ q.answer }}',{% endfor %}])">
        {% for q in questions %}
            <h3> {{ q.id }}.  {{ q.question }}</h3>
            <!-- 问题选项代码省略 -->
        {% endfor %}
        <input type="submit" value="Submit Answer">
    </form>
    <br><br>
</section>

相关JS代码

function submitAnswers(answers) {

    var total = answers.length;
    var score = 0;
    var choice = []

    //dynamic method to get selected option
    for (var i = 1; i <= total; i++) {
        choice[i] = document.forms["quizForm"]["q" + i].value;
    }

    //dynamic method 1 for checking answer
    for (i = 1; i <= total; i++) {
        if (choice[i] == answers[i - 1]) {
            score++;
        }
    }

    //Display Result
    var results = document.getElementById('results');
    results.innerHTML = "<h3>You scored <span>" + score + "</span> out of <span>" + total + "</span></h3>"
    alert("You scored " + score + " out of " + total);

    return false;
}

问题原因

  1. 数组语法错误:Django模板循环生成answers数组时,最后一个元素后会多一个逗号,导致JS语法解析失败,函数未执行,表单直接默认提交刷新。
  2. 单选框取值错误:原JS中直接取document.forms["quizForm"]["q" + i].value不适用于单选框组,无法正确获取选中值,可能引发错误中断函数。
  3. DOM加载顺序问题:如果JS代码在DOM元素加载前执行,submitAnswers函数可能未被正确注册,onsubmit事件无法触发。

修复方案

1. 修正数组生成的逗号问题

修改模板中数组的生成方式,避免多余逗号:

<form name="quizForm" onsubmit="return submitAnswers(answers = [{% for q in questions %}{% if not forloop.first %},{% endif %}'{{ q.answer }}'{% endfor %}])">

或者使用Django过滤器简化写法(需确保questions是QuerySet):

<form name="quizForm" onsubmit="return submitAnswers(answers = ['{{ questions.values_list('answer', flat=True)|join:"', '" }}'])">

2. 修复单选框取值逻辑

如果问题选项是单选框,需要遍历找到选中的选项:

function submitAnswers(answers) {
    var total = answers.length;
    var score = 0;
    var choice = [];

    // 获取每个问题的选中选项
    for (var i = 1; i <= total; i++) {
        var radioGroup = document.forms["quizForm"]["q" + i];
        if (!radioGroup) {
            console.error("未找到名为q" + i + "的表单元素");
            return false;
        }
        // 遍历单选框组找选中项
        for (var j = 0; j < radioGroup.length; j++) {
            if (radioGroup[j].checked) {
                choice[i] = radioGroup[j].value;
                break;
            }
        }
    }

    // 计分逻辑
    for (i = 1; i <= total; i++) {
        if (choice[i] === answers[i - 1]) {
            score++;
        }
    }

    // 显示结果
    var results = document.getElementById('results');
    results.innerHTML = "<h3>You scored <span>" + score + "</span> out of <span>" + total + "</span></h3>";
    alert("You scored " + score + " out of " + total);

    return false;
}

3. 确保JS代码在DOM加载后执行

将JS代码放在HTML底部(</body>标签前),或者用DOM加载事件包裹:

document.addEventListener('DOMContentLoaded', function() {
    window.submitAnswers = function(answers) {
        // 上述修复后的函数内容
    };
});

4. 检查表单元素命名

确保每个问题的选项组name属性与JS中的q + i对应,比如循环中生成:

{% for q in questions %}
    <h3>{{ q.id }}. {{ q.question }}</h3>
    <input type="radio" name="q{{ forloop.counter }}" value="A"> A<br>
    <input type="radio" name="q{{ forloop.counter }}" value="B"> B<br>
    <!-- 其他选项 -->
{% endfor %}

内容的提问来源于stack exchange,提问作者Raja Uzair Zia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:01:20