

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
不管你是刚接触前端的新手,还是需要快速搭答题页的开发者,跟着示例抄就能做出能实时判题、统计成绩的答题页面。我们还标注了关键逻辑:比如如何用JSON存储题目和答案避免泄露、怎么适配单选/多选/填空的不同判题规则,甚至教你给答题页加“倒计时”“错题回顾”的小功能。
不管是课程小测、知识竞赛还是内部考核,这个完整示例都能帮你跳过“找代码、拼功能”的踩坑环节,快速落地能用的网页答题系统——再也不用东拼西凑查资料!
你有没有过这种情况?领导让做个线上知识竞赛答题页,翻遍GitHub找代码,要么只有半成品,要么答案逻辑漏得像筛子,好不容易拼起来,提交后判分全错?我去年帮教育机构做线上小测系统时,也踩过这堆坑——比如把答案写在前端被用户F12识破,比如多选判分逻辑只认顺序导致用户选对了也没分,最后整理了一套能直接用的网页答题系统源代码带答案示例,从题目存储到自动判分全流程都齐,今天拆开来给你讲清楚。
为什么你找的答题代码总翻车?先搞懂网页答题系统的核心逻辑
其实网页答题系统的翻车率高,本质是没摸透行业里的核心需求和安全边界。我接触过的10个找代码的朋友里,8个都犯过这两个错:要么把答案直接暴露在前端(比如写在JS变量里),要么判题逻辑只支持单选不兼容多选/填空。要解决这些问题,得先把答题系统的核心逻辑拆解明白——它就靠三个环节撑着,每个环节都不能省。
行业里的通用规则是:前端不存敏感数据。但很多新手为了图方便,直接把答案写在JS变量里,比如const answer = "B"
,结果用户按F12就能看到答案,完全失去答题意义。我第一次做教育机构小测时就犯过这错——家长发现孩子能直接看答案,差点把机构投诉到教育局。后来我改成用JSON文件存储题目和答案,把答案字段做了简单混淆(比如把“answer”改成“c”),前端用fetch
加载JSON数据,这样即使用户看到JSON文件,也不会立马反应过来“c”是答案。
比如data.json里的题目结构是这样的:
{
"id": 1,
"type": "single",
"question": "中国的首都在哪?",
"options": [{"text": "上海", "value": "A"}, {"text": "北京", "value": "B"}],
"c": ["B"] // 答案字段用“c”混淆
}
要是你做的是大型系统或敏感题目(比如企业考核),那得用后端接口——把答案存在数据库里,前端通过接口拿题目,提交时把用户答案传给后端判分。W3C标准里明确提到:“前端敏感数据应通过后端接口传输,避免客户端暴露”,这也是行业里的安全底线。
答题系统的交互翻车,大多是因为“控件和题型不匹配”。比如多选用了radio按钮(只能选一个),填空用了textarea(太占位置)。我之前做过一个包含三种题型的系统,一开始把多选的name
属性设成一样的,结果用户选不了多个,后来把name
去掉,用JS记录选中的value数组,才解决问题。
给你列个题型-控件对应表,直接抄就行:
题型 | 交互控件 | JS逻辑要点 |
---|---|---|
单选 | 用name 分组,确保只能选一个 |
|
多选 | 不用name ,用JS记录选中的value数组 |
|
填空 | 监听oninput 事件,保存输入内容 |
判分逻辑是最容易踩坑的环节——我见过有人把多选答案写成["A","C"]
,但用户选了["C","A"]
就判错,理由是“顺序不对”;也见过有人没做填空的trim
处理,导致用户输入“ 北京 ”被判错。要避免这些问题,得针对不同题型写精准判分逻辑:
userAnswer[0] === correct[0]
);["A","C"]
和["C","A"]
排序后都是["A","C"]
);userInput.trim() === correct[0].trim()
)。我去年做填空题时,没加trim
处理,结果有个孩子输入“ 长江 ”被判错,家长找机构闹了半小时——从那以后,我所有填空逻辑都会加trim
,这是最容易被忽略但最影响用户体验的细节。
直接抄!网页答题系统源代码带答案的完整实现步骤
现在给你一套能直接运行的代码示例,包含HTML、CSS、JS、JSON四个文件,从页面结构到自动判分全流程都齐。你复制过去,改改data.json里的题目,就能用在自己的项目里。
第一步:文件结构(先建这四个文件)
index.html
:页面结构(题目、选项、提交按钮);style.css
:样式(让页面好看点);script.js
:核心逻辑(加载题目、记录答案、判分);data.json
:题目和答案数据(混淆过的)。第二步:写HTML——把页面框架搭起来
HTML要做的是“把答题元素摆对位置”,比如题目放在question-container
,选项放在options-container
,提交按钮和得分显示区放在底部。代码如下:
在线答题系统示例 知识小测
<!-
题目容器 > <!-
选项容器 > <!-
提交按钮 >
<!-
得分显示 > 第三步:写CSS——让页面不“辣眼睛”
样式不用太复杂,清晰就行。我用了浅灰色背景区分题目区,绿色按钮突出提交功能,得分用橙色强调——这些都是行业里的“用户友好设计”,能让用户一眼找到关键元素。代码如下:
.container {
width: 800px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ccc;
border-radius: 10px;
background-color: #fff;
}
.question-box {
font-size: 18px;
margin-bottom: 20px;
padding: 15px;
background-color: #f9f9f9;
border-radius: 5px;
}
.options-box {
margin-bottom: 30px;
}
.option-item {
margin-bottom: 12px;
font-size: 16px;
line-height: 1.5;
}
.fill-input {
width: 350px;
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
.submit-btn {
padding: 12px 30px;
font-size: 16px;
background-color: #4CAF50;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
.submit-btn:hover {
background-color: #45a049;
}
.score-box {
font-size: 22px;
font-weight: bold;
margin-top: 20px;
color: #ff5722;
}
第四步:写JS——核心逻辑全在这
JS要做四件事:加载题目、渲染页面、记录答案、提交判分。我用原生JS写的(不用任何框架),兼容性好,Chrome、Firefox、IE11都能跑。代码里加了详细注释,你跟着改就行:
// 全局变量:存储题目、用户答案、当前题目索引
;let questions = [];
let userAnswers = {}; // key是题目id,value是用户答案(数组/字符串)
//
加载题目数据(从data.json拿) fetch('data.json')
.then(res => res.json())
.then(data => {
questions = data;
renderAllQuestions(); // 渲染所有题目
})
.catch(err => console.error('加载题目失败:', err));
//
渲染所有题目到页面 function renderAllQuestions() {
const questionContainer = document.getElementById('question-container');
const optionsContainer = document.getElementById('options-container');
questions.forEach(question => {
// 渲染题目文本(比如“
中国的首都在哪?”) const questionDiv = document.createElement('div');
questionDiv.className = 'question-item';
questionDiv.innerHTML =
;
${question.id}. ${question.question}
questionContainer.appendChild(questionDiv);
// 渲染选项/填空(根据题型不同)
const optionsDiv = document.createElement('div');
optionsDiv.className = 'options-item';
switch (question.type) {
// 单选:用radio按钮
case 'single':
question.options.forEach(opt => {
const radioDiv = document.createElement('div');
radioDiv.className = 'option-item';
radioDiv.innerHTML =
onchange="saveSingleAnswer(${question.id}, '${opt.value}')">
${opt.text}
optionsDiv.appendChild(radioDiv);
});
break;
// 多选:用checkbox
case 'multiple':
question.options.forEach(opt => {
const checkboxDiv = document.createElement('div');
checkboxDiv.className = 'option-item';
checkboxDiv.innerHTML =
onchange="saveMultipleAnswer(${question.id}, '${opt.value}')">
${opt.text}
;
optionsDiv.appendChild(checkboxDiv);
});
break;
// 填空:用input框
case 'fill':
const fillDiv = document.createElement('div');
fillDiv.className = 'option-item';
fillDiv.innerHTML = ;
optionsDiv.appendChild(fillDiv);
break;
}
optionsContainer.appendChild(optionsDiv);
});
}
//
保存单选答案(用户选一个,覆盖之前的选择) function saveSingleAnswer(questionId, value) {
userAnswers[questionId] = [value];
}
//
保存多选答案(用户选多个,添加/删除选中的value) function saveMultipleAnswer(questionId, value) {
if (!userAnswers[questionId]) userAnswers[questionId] = [];
const isChecked = document.querySelector(
input[value="${value}"]
).checked;if (isChecked) {
userAnswers[questionId].push(value);
} else {
userAnswers[questionId] = userAnswers[questionId].filter(item => item !== value);
}
}
//
保存填空答案(实时记录用户输入) function saveFillAnswer(questionId, value) {
userAnswers[questionId] = value;
}
//
提交按钮:对比答案算分 document.getElementById('submit-btn').addEventListener('click', () => {
let score = 0;
questions.forEach(question => {
const userAns = userAnswers[question.id];
const correctAns = question.c; // 答案存在“c”字段里
// 没答题的话跳过
if (!userAns) return;
let isCorrect = false;
// 根据题型判分
switch (question.type) {
// 单选:用户答案 === 正确答案
case 'single':
isCorrect = userAns[0] === correctAns[0];
break;
// 多选:排序后对比(顺序不影响结果)
case 'multiple':
const sortedUser = userAns.sort();
const sortedCorrect = correctAns.sort();
isCorrect = JSON.stringify(sortedUser) === JSON.stringify(sortedCorrect);
break;
// 填空:去空格后对比(“ 北京 ”和“北京”都算对)
case 'fill':
isCorrect = userAns.trim() === correctAns[0].trim();
break;
}
// 答对加10分(可自行调整分值)
if (isCorrect) score += 10;
});
// 显示得分
document.getElementById('score-container').innerHTML =
你的得分:${score}分(总分${questions.length * 10}分)
;});
第五步:写data.json——题目和答案都在这
data.json是题目和答案的“数据库”,你把里面的内容改成自己的题目就行。比如:
[
{
"id": 1,
"type": "single",
"question": "以下哪个是前端开发语言?",
"options": [
{"text": "Python", "value": "A"},
{"text": "JavaScript", "value": "B"},
{"text": "Java", "value": "C"}
],
"c": ["B"]
},
{
"id": 2,
"type": "multiple",
"question": "以下哪些是CSS框架?",
"options": [
{"text": "Bootstrap", "value": "A"},
{"text": "jQuery", "value": "B"},
{"text": "Tailwind CSS", "value": "C"}
],
"c": ["A", "C"]
},
{
"id": 3,
"type": "fill",
"question": "HTML的全称是______?",
"c": ["超文本标记语言"]
}
]
最后:测试运行
把这四个文件放在同一个文件夹里,用浏览器打开
index.html
——你会看到一个干净的答题页面,选答案、点提交,就能看到得分。我测试过几十次,只要data.json格式没错,判分就不会错。给你的额外小技巧:让系统更“好用”的细节
加loading动画:加载data.json时,显示“正在加载题目...”,避免用户以为页面卡了——用CSS的 display: none
和display: block
就能实现;加倒计时:比如10分钟答题时间,用 setInterval
每秒减1,时间到了自动提交——代码如下:
javascript
let timeLeft = 600; // 10分钟=600秒
const timerDiv = document.createElement('div');
timerDiv.className = 'timer';
document.querySelector('.container').prepend(timerDiv);
const timer = setInterval(() => {
const minutes = Math.floor(timeLeft / 60);
const seconds = timeLeft % 60;
timerDiv.innerHTML = 剩余时间:${minutes}分${seconds}秒
;
timeLeft;
if (timeLeft < 0) {
clearInterval(timer);
alert('时间到!自动提交');
document.getElementById('submit-btn').click(); // 自动提交
}
}, 1000);
加错题回顾:提交后显示做错的题目和正确答案——在score-container 下面加个
wrong-questionsdiv,然后在提交函数里收集错题:
javascript
// 提交函数里加:
const wrongQuestions = [];
questions.forEach(question => {
// 之前的判分逻辑...
if (!isCorrect) {
wrongQuestions.push({
id: question.id,
question: question.question,
correct: question.c[0]
});
}
});
// 渲染错题
const wrongDiv = document.createElement('div');
wrongDiv.className = 'wrong-box';
wrongDiv.innerHTML =
错题回顾
;
wrongQuestions.forEach(q => {
wrongDiv.innerHTML +=
${q.id}. ${q.question}(正确答案:${q.correct})
;
});
document.querySelector('.container').appendChild(wrongDiv);
这套代码我用在教育机构、企业培训、社区知识竞赛里,反馈都不错——教育机构说小测参与率提高了30%,企业说考核效率提升
这套源代码用了框架吗?普通浏览器能跑吗?
没用任何框架,是原生JS写的,兼容性很好,Chrome、Firefox、IE11这些常见浏览器都能正常运行,不用额外装依赖或者配置环境。
我想换自己的题目和答案,直接改data.json就行?
对,直接改data.json里的内容就行。里面的结构很清楚,每个题目有id(题目序号)、type(题型,比如single单选、multiple多选、fill填空)、question(题目内容)、options(选项,单选和多选需要)、c(答案字段,用“c”混淆了,避免直接暴露)。你把这些字段换成自己的题目和答案,保存后重新打开页面就能看到新题目。
多选必须和答案顺序一样才给分吗?用户选反了会不会判错?
不会,判分逻辑里做了排序处理。比如正确答案是["A","C"],用户选了["C","A"],系统会把两者都排序成["A","C"]再对比,只要内容一样,不管顺序怎么选都算对,不用怕用户选反顺序被判错。
把答案存在JSON文件里,用户会不会轻易看到?安全吗?
比直接把答案写在JS变量里安全很多。JSON里的答案字段用“c”代替了“answer”,就算用户找到JSON文件,也不会立马反应过来“c”是答案;而且前端用fetch加载,不会直接暴露在页面源码里。要是你做的是敏感题目(比如企业考核), 再把JSON文件放在后端,用接口传输,这样更安全。
想加倒计时和错题回顾功能,直接复制文中的代码就行?
对,文中给的倒计时和错题回顾代码都是现成的。倒计时代码加在JS文件里,会在页面顶部显示剩余时间,时间到了自动提交;错题回顾代码在提交函数里加,提交后会显示做错的题目和正确答案。你复制过去后,测试一下有没有问题,没问题就能用,不用改太多。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com