好友
阅读权限35
听众
最后登录1970-1-1
|
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>驾照扣分题库练习</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#10B981',
accent: '#F59E0B',
danger: '#EF4444',
neutral: '#1F2937',
'neutral-light': '#F3F4F6'
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.card-shadow {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.card-hover {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.option-hover {
transition: all 0.2s ease;
}
.option-hover:hover {
background-color: rgba(59, 130, 246, 0.1);
border-color: #3B82F6;
}
.scale-in {
animation: scaleIn 0.3s ease forwards;
}
@keyframes scaleIn {
from { transform: scale(0.95); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
.fade-in {
animation: fadeIn 0.5s ease forwards;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen font-sans text-neutral">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- 顶部导航栏 -->
<header class="mb-8">
<div class="flex justify-between items-center">
<h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-primary">
<i class="fa-solid fa-car text-accent mr-2"></i>驾照扣分题库练习
</h1>
<div id="wrong-count" class="bg-white rounded-full px-4 py-2 shadow-md flex items-center card-hover">
<i class="fa-solid fa-exclamation-triangle text-danger mr-2"></i>
<span class="font-medium">错题数量: <span id="wrong-count-value">0</span></span>
</div>
</div>
</header>
<!-- 主内容区 -->
<main class="bg-white rounded-2xl shadow-xl p-6 md:p-8 mb-8 card-shadow">
<!-- 开始界面 -->
<div id="start-screen" class="scale-in">
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-24 h-24 bg-primary/10 rounded-full mb-4">
<i class="fa-solid fa-question-circle text-4xl text-primary"></i>
</div>
<h2 class="text-[clamp(1.5rem,3vw,2rem)] font-bold mb-3">准备开始练习吗?</h2>
<p class="text-gray-600 mb-6">测试你的交通法规知识,掌握驾照扣分规则</p>
<button id="start-btn" class="bg-primary hover:bg-primary/90 text-white font-bold py-3 px-8 rounded-full shadow-lg transform transition hover:scale-105 focus:outline-none focus:ring-2 focus:ring-primary/50">
<i class="fa-solid fa-play-circle mr-2"></i>开始练习
</button>
</div>
</div>
<!-- 题目界面 -->
<div id="question-screen" class="hidden fade-in">
<div class="mb-6">
<div class="flex justify-between items-center mb-4">
<div class="bg-primary/10 text-primary px-3 py-1 rounded-full text-sm font-medium">
<i class="fa-solid fa-trophy mr-1"></i> 练习模式
</div>
<button id="exit-btn" class="text-gray-500 hover:text-danger transition">
<i class="fa-solid fa-times-circle"></i>
</button>
</div>
<div id="question-container" class="mb-6">
<h3 class="text-xl font-bold mb-4" id="question-text"></h3>
<div id="options-container" class="space-y-3"></div>
</div>
<div id="feedback-container" class="hidden mt-6 p-4 rounded-lg scale-in"></div>
</div>
</div>
<!-- 错题统计界面 -->
<div id="wrong-questions-screen" class="hidden fade-in">
<div class="text-center mb-6">
<h2 class="text-2xl font-bold mb-2">我的错题</h2>
<p class="text-gray-600">以下是你需要加强练习的题目</p>
</div>
<div id="wrong-questions-list" class="space-y-4 max-h-[500px] overflow-y-auto pr-2"></div>
<div class="mt-6 text-center">
<button id="back-from-wrong-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-bold py-2 px-6 rounded-full transition">
返回练习
</button>
</div>
</div>
</main>
<!-- 页脚 -->
<footer class="text-center text-gray-500 text-sm">
<p>© 2025 驾照扣分题库练习应用 | 提升你的交通法规知识</p>
</footer>
</div>
<script>
// 驾照扣分题库
const questions = [
{
"question": "酒后驾驶机动车的,一次记多少分?",
"options": ["A. 6分", "B. 12分", "C. 3分", "D. 9分"],
"answer": "B"
},
{
"question": "在高速公路上倒车,一次记多少分?",
"options": ["A. 1分", "B. 6分", "C. 12分", "D. 9分"],
"answer": "C"
},
{
"question": "驾驶机动车违反道路交通信号灯通行时,一次记多少分?",
"options": ["A. 2分", "B. 6分", "C. 3分", "D. 12分"],
"answer": "B"
},
{
"question": "驾驶机动车未按规定使用灯光的,一次记多少分?",
"options": ["A. 1分", "B. 2分", "C. 3分", "D. 不记分"],
"answer": "A"
},
// 扣12分题型
{
"question": "驾驶伪造号牌的机动车上路行驶,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "D"
},
{
"question": "造成交通事故后逃逸致人轻伤,尚不构成犯罪的,一次记多少分?",
"options": ["A. 6分", "B. 9分", "C. 12分", "D. 不记分"],
"answer": "C"
},
{
"question": "驾驶小型客车在高速公路超速50%以上,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "D"
},
{
"question": "代替他人接受交通违法处罚牟取经济利益的,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "D"
},
// 扣9分题型
{
"question": "驾驶未悬挂机动车号牌的车辆上路行驶,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "C"
},
{
"question": "驾驶与准驾车型不符的机动车的,一次记多少分?",
"options": ["A. 3分", "B. 9分", "C. 6分", "D. 12分"],
"answer": "B"
},
{
"question": "驾驶7座以上载客汽车超员50%未达100%的,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "C"
},
// 扣6分题型
{
"question": "驾驶机动车在高速公路占用应急车道行驶的,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 2分"],
"answer": "B"
},
{
"question": "驾驶货车超过最大允许总质量30%未达50%的,一次记多少分?",
"options": ["A. 1分", "B. 3分", "C. 6分", "D. 9分"],
"answer": "C"
},
{
"question": "驾驶证被暂扣期间驾驶机动车的,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "B"
},
{
"question": "驾驶机动车不避让校车的,一次记多少分?",
"options": ["A. 3分", "B. 6分", "C. 9分", "D. 12分"],
"answer": "B"
},
// 扣3分题型
{
"question": "驾驶机动车时拨打接听手持电话的,一次记多少分?",
"options": ["A. 1分", "B. 2分", "C. 3分", "D. 6分"],
"answer": "C"
},
{
"question": "在高速公路不按规定车道行驶的,一次记多少分?",
"options": ["A. 1分", "B. 3分", "C. 6分", "D. 9分"],
"answer": "B"
},
{
"question": "驾驶机动车在普通道路超速20%未达50%的,一次记多少分?",
"options": ["A. 1分", "B. 3分", "C. 6分", "D. 9分"],
"answer": "B"
},
{
"question": "车辆发生故障未按规定设置警示标志的,一次记多少分?",
"options": ["A. 1分", "B. 3分", "C. 6分", "D. 9分"],
"answer": "B"
},
// 扣1分题型
{
"question": "驾驶机动车未按规定使用灯光的,一次记多少分?",
"options": ["A. 1分", "B. 2分", "C. 3分", "D. 不记分"],
"answer": "A"
},
{
"question": "驾驶摩托车不戴安全头盔的,一次记多少分?",
"options": ["A. 1分", "B. 2分", "C. 3分", "D. 6分"],
"answer": "A"
},
{
"question": "驾驶货车长宽高超过规定的,一次记多少分?",
"options": ["A. 1分", "B. 3分", "C. 6分", "D. 9分"],
"answer": "A"
}
];
// 错题库
let wrongQuestions = [];
// 当前题目
let currentQuestion = null;
// 正确连续答对次数目标
const correctStreakGoal = 3;
// DOM 元素
const startScreen = document.getElementById('start-screen');
const questionScreen = document.getElementById('question-screen');
const wrongQuestionsScreen = document.getElementById('wrong-questions-screen');
const startBtn = document.getElementById('start-btn');
const exitBtn = document.getElementById('exit-btn');
const backFromWrongBtn = document.getElementById('back-from-wrong-btn');
const questionText = document.getElementById('question-text');
const optionsContainer = document.getElementById('options-container');
const feedbackContainer = document.getElementById('feedback-container');
const wrongCountValue = document.getElementById('wrong-count-value');
const wrongQuestionsList = document.getElementById('wrong-questions-list');
const wrongCount = document.getElementById('wrong-count');
// 初始化
function init() {
// 从本地存储加载错题库
loadWrongQuestions();
updateWrongCount();
// 绑定事件
startBtn.addEventListener('click', startPractice);
exitBtn.addEventListener('click', exitPractice);
backFromWrongBtn.addEventListener('click', showStartScreen);
wrongCount.addEventListener('click', showWrongQuestions);
}
// 开始练习
function startPractice() {
startScreen.classList.add('hidden');
questionScreen.classList.remove('hidden');
loadNextQuestion();
}
// 退出练习
function exitPractice() {
questionScreen.classList.add('hidden');
startScreen.classList.remove('hidden');
saveWrongQuestions();
}
// 显示错题库
function showWrongQuestions() {
if (wrongQuestions.length === 0) {
alert('恭喜!你的错题库是空的!');
return;
}
questionScreen.classList.add('hidden');
wrongQuestionsScreen.classList.remove('hidden');
renderWrongQuestionsList();
}
// 显示开始界面
function showStartScreen() {
wrongQuestionsScreen.classList.add('hidden');
startScreen.classList.remove('hidden');
}
// 加载下一题
function loadNextQuestion() {
// 优先处理错题库
if (wrongQuestions.length > 0 && Math.random() < 0.7) {
const randomIndex = Math.floor(Math.random() * wrongQuestions.length);
currentQuestion = wrongQuestions[randomIndex];
} else {
// 随机选择新题目
currentQuestion = questions[Math.floor(Math.random() * questions.length)];
}
renderQuestion();
}
// 渲染题目
function renderQuestion() {
questionText.textContent = currentQuestion.question;
optionsContainer.innerHTML = '';
// 隐藏反馈容器
feedbackContainer.classList.add('hidden');
// 渲染选项
currentQuestion.options.forEach(option => {
const optionElement = document.createElement('div');
const optionLetter = option.split('.')[0];
optionElement.className = 'border border-gray-200 rounded-lg p-4 option-hover cursor-pointer';
optionElement.innerHTML = `
<span class="inline-block w-8 h-8 rounded-full bg-primary/10 text-primary font-bold text-center mr-2">
${optionLetter}
</span>
${option}
`;
optionElement.addEventListener('click', () => checkAnswer(optionLetter));
optionsContainer.appendChild(optionElement);
});
}
// 检查答案
function checkAnswer(userAnswer) {
const isCorrect = userAnswer === currentQuestion.answer;
// 禁用所有选项
Array.from(optionsContainer.children).forEach(option => {
option.classList.remove('option-hover', 'cursor-pointer');
option.classList.add('opacity-70');
// 高亮正确答案
const optionLetter = option.textContent.trim().charAt(0);
if (optionLetter === currentQuestion.answer) {
option.classList.add('border-secondary', 'bg-secondary/10');
}
});
// 显示反馈
feedbackContainer.innerHTML = '';
feedbackContainer.classList.remove('hidden', 'bg-danger/10', 'bg-secondary/10', 'border-danger', 'border-secondary');
if (isCorrect) {
feedbackContainer.classList.add('bg-secondary/10', 'border-secondary');
feedbackContainer.innerHTML = `
<div class="flex items-center">
<i class="fa-solid fa-check-circle text-2xl text-secondary mr-3"></i>
<div>
<p class="font-bold text-secondary">回答正确!</p>
${currentQuestion.explanation || ''}
</div>
</div>
`;
// 如果是错题,增加连续答对次数
const wrongQuestionIndex = wrongQuestions.findIndex(q => q.question === currentQuestion.question);
if (wrongQuestionIndex !== -1) {
wrongQuestions[wrongQuestionIndex].correctStreak += 1;
// 如果达到目标,从错题库移除
if (wrongQuestions[wrongQuestionIndex].correctStreak >= correctStreakGoal) {
setTimeout(() => {
const removedQuestion = wrongQuestions.splice(wrongQuestionIndex, 1)[0];
updateWrongCount();
// 显示提示
showToast(`🎉 你已掌握了"${removedQuestion.question.substring(0, 20)}...",该题已从错题库中移除!`);
}, 1000);
}
}
} else {
feedbackContainer.classList.add('bg-danger/10', 'border-danger');
feedbackContainer.innerHTML = `
<div class="flex items-center">
<i class="fa-solid fa-times-circle text-2xl text-danger mr-3"></i>
<div>
<p class="font-bold text-danger">回答错误!</p>
<p>正确答案是:${currentQuestion.answer}</p>
${currentQuestion.explanation || ''}
</div>
</div>
`;
// 如果不是错题,添加到错题库
const wrongQuestionIndex = wrongQuestions.findIndex(q => q.question === currentQuestion.question);
if (wrongQuestionIndex === -1) {
wrongQuestions.push({
...currentQuestion,
correctStreak: 0
});
updateWrongCount();
} else {
// 重置连续答对次数
wrongQuestions[wrongQuestionIndex].correctStreak = 0;
}
}
// 保存错题库
saveWrongQuestions();
// 3秒后自动加载下一题
setTimeout(loadNextQuestion, 3000);
}
// 更新错题库数量
function updateWrongCount() {
wrongCountValue.textContent = wrongQuestions.length;
}
// 渲染错题库列表
function renderWrongQuestionsList() {
wrongQuestionsList.innerHTML = '';
if (wrongQuestions.length === 0) {
wrongQuestionsList.innerHTML = `
<div class="text-center py-10 text-gray-500">
<i class="fa-solid fa-check-circle text-4xl mb-3 text-secondary"></i>
<p>你的错题库是空的!继续保持!</p>
</div>
`;
return;
}
wrongQuestions.forEach((question, index) => {
const questionElement = document.createElement('div');
questionElement.className = 'border border-gray-200 rounded-lg p-4 card-shadow card-hover';
// 计算进度条
const progress = (question.correctStreak / correctStreakGoal) * 100;
const progressClass = progress >= 100 ? 'bg-secondary' : 'bg-accent';
questionElement.innerHTML = `
<div class="flex justify-between items-start mb-3">
<h4 class="font-bold">${index + 1}. ${question.question}</h4>
<span class="bg-danger/10 text-danger text-xs px-2 py-1 rounded-full">
错误
</span>
</div>
<div class="mb-3 text-sm text-gray-600">
<p>正确答案: ${question.answer}</p>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5 mb-2">
<div class="${progressClass} h-2.5 rounded-full" style="width: ${progress}%"></div>
</div>
<div class="text-xs text-gray-500 flex justify-between">
<span>连续答对: ${question.correctStreak}/${correctStreakGoal}</span>
<button class="text-primary hover:underline" onclick="practiceWrongQuestion(${index})">
练习此题
</button>
</div>
`;
wrongQuestionsList.appendChild(questionElement);
});
}
// 练习指定错题(在全局作用域中定义,以便在HTML中调用)
window.practiceWrongQuestion = function(index) {
if (index >= 0 && index < wrongQuestions.length) {
currentQuestion = wrongQuestions[index];
wrongQuestionsScreen.classList.add('hidden');
questionScreen.classList.remove('hidden');
renderQuestion();
}
};
// 保存错题库到本地存储
function saveWrongQuestions() {
localStorage.setItem('drivingTestWrongQuestions', JSON.stringify(wrongQuestions));
}
// 从本地存储加载错题库
function loadWrongQuestions() {
const savedWrongQuestions = localStorage.getItem('drivingTestWrongQuestions');
if (savedWrongQuestions) {
wrongQuestions = JSON.parse(savedWrongQuestions);
}
}
// 显示提示消息
function showToast(message) {
// 创建toast元素
const toast = document.createElement('div');
toast.className = 'fixed bottom-4 right-4 bg-neutral text-white px-4 py-3 rounded-lg shadow-lg z-50 scale-in';
toast.textContent = message;
// 添加到页面
document.body.appendChild(toast);
// 3秒后移除
setTimeout(() => {
toast.classList.add('fade-out');
setTimeout(() => {
document.body.removeChild(toast);
}, 500);
}, 3000);
}
// 初始化应用
document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html> |
免费评分
-
查看全部评分
|