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; }
问题原因
- 数组语法错误:Django模板循环生成answers数组时,最后一个元素后会多一个逗号,导致JS语法解析失败,函数未执行,表单直接默认提交刷新。
- 单选框取值错误:原JS中直接取
document.forms["quizForm"]["q" + i].value不适用于单选框组,无法正确获取选中值,可能引发错误中断函数。 - 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
相关产品推荐
相关产品推荐

