1099

5 分钟

#算术练习

这是一个基于浏览器的四则运算限时答题系统,用户可以自定义生成包含加减乘除运算的数学题目,在限定时间内完成答题挑战,系统会自动批改并统计成绩。

四则运算

#主要特性

智能题目生成

  • 随机生成1-99范围内的整数四则运算题目
  • 智能避免简单题目:不会出现除以1或结果为1的除法题
  • 确保所有运算结果为正整数
  • 可自定义题目数量(10-100题)

灵活配置选项

  • 运算符选择:可自由组合加减乘除四种运算
  • 数字范围:提供1-9、1-99、10-99三种范围选择
  • 时间设置:答题时间30-600秒可调,默认3分钟
  • 题目数量:10-100题可调,默认40题

实时答题体验

  • 倒计时显示剩余时间,最后30秒变红提醒
  • 实时答案验证:输入即显示正确/错误状态
  • 答题统计面板:实时显示已答、正确、剩余题目数
  • 键盘导航支持:Enter键跳转下一题,Ctrl+Enter提交

友好结果反馈

  • 显示答对题目数/总题目数
  • 统计错误题目数量(不提示具体位置,保护答题体验)
  • 显示总用时
  • 根据正确率提供不同的鼓励信息
  • 完美通关有特别祝贺信息

响应式设计

  • 适配桌面、平板、手机各种屏幕尺寸
  • 自动调整题目网格布局
  • 移动端优化操作体验

#使用场景

教育用途

  • 小学数学课堂练习
  • 心算能力训练
  • 考试前复习

个人提升

  • 大脑敏捷度训练
  • 心算能力提升
  • 注意力集中训练

趣味挑战

  • 与朋友比拼计算速度
  • 家庭亲子数学游戏
  • 工作间隙脑力放松

#技术亮点

  • 纯前端实现:无需后端,单HTML文件运行
  • 智能算法:确保题目多样性和合理性
  • 实时反馈:即时验证和统计
  • 数据安全:所有操作均在浏览器本地完成
  • 性能优化:流畅的答题体验,无页面刷新

#源码

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>四则运算限时挑战</title> <link rel="canonical" href="https://xplanc.org/primers/document/zh/03.HTML/90.实践案例/01.算术练习.md"/> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f5f7fa; color: #333; line-height: 1.6; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; } .container { max-width: 1200px; width: 100%; margin: 0 auto; padding: 30px; background-color: white; border-radius: 15px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); } header { text-align: center; margin-bottom: 40px; } h1 { color: #2c3e50; font-size: 2.5rem; margin-bottom: 15px; background: linear-gradient(90deg, #3498db, #2ecc71); -webkit-background-clip: text; background-clip: text; color: transparent; } .description { color: #7f8c8d; font-size: 1.1rem; max-width: 800px; margin: 0 auto 20px; } .config-panel { background-color: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 30px; display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; align-items: center; } .config-item { display: flex; align-items: center; gap: 10px; } .config-item label { font-weight: 600; color: #2c3e50; } .config-item input, .config-item select { padding: 8px 12px; border: 1px solid #ddd; border-radius: 5px; width: 100px; text-align: center; font-size: 1rem; } .control-panel { display: flex; justify-content: center; gap: 20px; margin-bottom: 30px; } .btn { padding: 15px 40px; border: none; border-radius: 8px; font-size: 1.2rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; } .btn-primary { background-color: #3498db; color: white; } .btn-primary:hover { background-color: #2980b9; transform: translateY(-2px); } .btn-secondary { background-color: #2ecc71; color: white; } .btn-secondary:hover { background-color: #27ae60; transform: translateY(-2px); } .timer-container { text-align: center; margin-bottom: 30px; } .timer { font-size: 3.5rem; font-weight: 700; color: #e74c3c; padding: 10px 20px; border-radius: 10px; background-color: #fef5f5; display: inline-block; margin-bottom: 10px; min-width: 180px; } .timer-label { font-size: 1.2rem; color: #7f8c8d; font-weight: 600; } .questions-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; margin-bottom: 30px; } .question-item { padding: 15px; background-color: #f8f9fa; border-radius: 8px; border-left: 5px solid #3498db; display: flex; align-items: center; gap: 10px; } .question-number { font-weight: 700; color: #3498db; min-width: 30px; } .question-text { flex-grow: 1; font-size: 1.1rem; } .question-answer { width: 70px; padding: 8px 10px; border: 2px solid #ddd; border-radius: 5px; text-align: center; font-size: 1rem; transition: border-color 0.3s; } .question-answer:focus { outline: none; border-color: #3498db; } .question-answer.correct { border-color: #2ecc71; background-color: #eafaf1; } .question-answer.incorrect { border-color: #e74c3c; background-color: #fdedec; } .result-container { text-align: center; padding: 30px; background-color: #f8f9fa; border-radius: 10px; margin-top: 30px; display: none; } .result-title { font-size: 2rem; margin-bottom: 20px; color: #2c3e50; } .result-score { font-size: 3rem; font-weight: 700; color: #2ecc71; margin-bottom: 20px; } .result-fail { color: #e74c3c; } .result-details { font-size: 1.2rem; color: #7f8c8d; } .result-error { color: #e74c3c; font-weight: 600; margin-top: 10px; } .hidden { display: none !important; } .operator-filter { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 10px; } .operator-option { display: flex; align-items: center; gap: 5px; } .operator-option input[type="checkbox"] { width: 18px; height: 18px; } .stats-panel { display: flex; justify-content: space-around; margin-top: 20px; margin-bottom: 20px; padding: 15px; background-color: #f1f8ff; border-radius: 8px; } .stat-item { text-align: center; } .stat-value { font-size: 1.8rem; font-weight: 700; color: #3498db; } .stat-label { font-size: 0.9rem; color: #7f8c8d; } input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; /* 保证在一些浏览器中不会出现额外边距 */ } @media (max-width: 768px) { .container { padding: 15px; } h1 { font-size: 2rem; } .questions-container { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; } .control-panel { flex-direction: column; align-items: center; } .btn { width: 100%; max-width: 300px; } .timer { font-size: 2.8rem; } .stats-panel { flex-direction: column; gap: 15px; } } @media (max-width: 480px) { .questions-container { grid-template-columns: 1fr; } .config-panel { flex-direction: column; align-items: flex-start; } .timer { font-size: 2.2rem; min-width: 150px; } .question-text { font-size: 1rem; } } </style> </head> <body> <div class="container"> <header> <h1>四则运算限时挑战</h1> <p class="description">点击开始答题后,系统将生成四则运算填空题。</p> <p class="description">您需要在限制时间内完成所有题目,全部答对即为挑战成功!</p> <p class="description">来自:<a class="description" target="_parent" href="https://xplanc.org/primers/document/zh/03.HTML/90.实践案例/01.算术练习.md">Primers 编程伙伴</a></p> <div class="operator-filter"> <div class="operator-option"> <input type="checkbox" id="addCheck" checked> <label for="addCheck">加法 (+)</label> </div> <div class="operator-option"> <input type="checkbox" id="subCheck" checked> <label for="subCheck">减法 (-)</label> </div> <div class="operator-option"> <input type="checkbox" id="mulCheck" checked> <label for="mulCheck">乘法 (×)</label> </div> <div class="operator-option"> <input type="checkbox" id="divCheck" checked> <label for="divCheck">除法 (÷)</label> </div> </div> </header> <div class="config-panel"> <div class="config-item"> <label for="timeLimit">答题时间:</label> <input type="number" id="timeLimit" value="600" min="30" max="6000"> <label ></label> </div> <div class="config-item"> <label for="questionCount">题目数量:</label> <input type="number" id="questionCount" value="30" min="10" max="100"> </div> <div class="config-item"> <label for="numberRange">数字范围:</label> <select id="numberRange"> <option value="1-9">1-9</option> <option value="1-99" selected>1-99</option> <option value="10-99">10-99</option> <option value="100-999">100-999</option> </select> </div> </div> <div class="control-panel"> <button id="startBtn" class="btn btn-primary">开始答题</button> <button id="submitBtn" class="btn btn-secondary hidden">提交答案</button> </div> <div class="timer-container"> <div class="timer" id="timer">--:--</div> <div class="timer-label">剩余时间</div> </div> <div class="stats-panel hidden" id="statsPanel"> <div class="stat-item"> <div class="stat-value" id="answeredCount">0</div> <div class="stat-label">已答题</div> </div> <div class="stat-item"> <div class="stat-value" id="remainingCount">40</div> <div class="stat-label">剩余题</div> </div> </div> <div id="questionsWrapper" class="hidden"> <div class="questions-container" id="questionsContainer"> <!-- 题目将动态生成在这里 --> </div> </div> <div class="result-container" id="resultContainer"> <h2 class="result-title">答题结果</h2> <div class="result-score" id="resultScore">40/40</div> <p class="result-details">您总共回答了 <span id="totalQuestions">40</span> 道题目</p> <p class="result-details">用时: <span id="timeUsed">00:00</span></p> <p class="result-error" id="errorCountInfo"></p> <p class="result-error" id="emptyCountInfo"></p> <p id="resultMessage"></p> </div> </div> <script> // 全局变量 let timer; let timeLeft; let questions = []; let userAnswers = {}; let isTestActive = false; let startTime; // DOM元素 const startBtn = document.getElementById('startBtn'); const submitBtn = document.getElementById('submitBtn'); const timerDisplay = document.getElementById('timer'); const questionsContainer = document.getElementById('questionsContainer'); const questionsWrapper = document.getElementById('questionsWrapper'); const resultContainer = document.getElementById('resultContainer'); const resultScore = document.getElementById('resultScore'); const totalQuestionsEl = document.getElementById('totalQuestions'); const timeUsedEl = document.getElementById('timeUsed'); const errorCountInfo = document.getElementById('errorCountInfo'); const emptyCountInfo = document.getElementById('emptyCountInfo'); const resultMessage = document.getElementById('resultMessage'); const timeLimitInput = document.getElementById('timeLimit'); const questionCountInput = document.getElementById('questionCount'); const numberRangeSelect = document.getElementById('numberRange'); const addCheck = document.getElementById('addCheck'); const subCheck = document.getElementById('subCheck'); const mulCheck = document.getElementById('mulCheck'); const divCheck = document.getElementById('divCheck'); const statsPanel = document.getElementById('statsPanel'); const answeredCountEl = document.getElementById('answeredCount'); const remainingCountEl = document.getElementById('remainingCount'); // 生成随机整数(根据范围) function getRandomNumber(min, max) { const MIN = Math.floor(min); const MAX = Math.floor(max); return Math.floor(Math.random() * (MAX - MIN + 1)) + MIN; } // 获取选中的运算符 function getSelectedOperators() { const operators = []; if (addCheck.checked) operators.push('+'); if (subCheck.checked) operators.push('-'); if (mulCheck.checked) operators.push('×'); if (divCheck.checked) operators.push('÷'); // 至少选择一个运算符 if (operators.length === 0) { operators.push('+', '-', '×', '÷'); addCheck.checked = true; subCheck.checked = true; mulCheck.checked = true; divCheck.checked = true; } return operators; } // 生成题目 function generateQuestions(count) { const newQuestions = []; const selectedOperators = getSelectedOperators(); const numberRange = numberRangeSelect.value; const items = numberRange.split(/\D+/); const min = parseInt(items[0]); const max = parseInt(items[1]); // 为每种运算符分配大致相等的题目数量 const operatorCounts = {}; selectedOperators.forEach(op => { operatorCounts[op] = Math.floor(count / selectedOperators.length); }); // 处理余数,确保总题目数正确 let remainder = count % selectedOperators.length; if (remainder > 0) { for (let i = 0; i < remainder; i++) { const op = selectedOperators[i % selectedOperators.length]; operatorCounts[op]++; } } // 生成每种运算符的题目 selectedOperators.forEach(operator => { const opCount = operatorCounts[operator]; for (let i = 0; i < opCount; i++) { let num1, num2, answer; let isValid = false; let attempts = 0; // 确保生成有效题目(结果为正整数且不是简单题目) while (!isValid && attempts < 100) { attempts++; switch (operator) { case '+': num1 = getRandomNumber(min, max); num2 = getRandomNumber(min, max); answer = num1 + num2; break; case '-': // 确保结果为正数且不是0 num1 = getRandomNumber(min, max); num2 = getRandomNumber(min, max); if (num1 < num2) { [num1, num2] = [num2, num1]; } answer = num1 - num2; break; case '×': // 限制乘法结果不超过1000且避免简单乘法 num1 = getRandomNumber(2, max / 2); num2 = getRandomNumber(2, max / num1); answer = num1 * num2; break; case '÷': // 生成除法题目,确保能整除且除数不是1 // 生成一个除数(确保不是1) num2 = getRandomNumber(2, max / 2); // 生成一个除数(确保不是1) answer = getRandomNumber(2, max / num2); // 计算被除数 num1 = answer * num2; break; } // 确保答案为正整数且不超过三位数 if (Number.isInteger(answer) && answer > 0 && answer <= 999) { // 对于减法,确保结果不是0 if (operator === '-' && answer === 0) { continue; } // 对于除法,确保除数不是1且答案大于1 if (operator === '÷' && (num2 === 1 || answer === 1)) { continue; } // 确保不重复 if (newQuestions.some(q => q.num1 === num1 && q.num2 === num2 && q.operator === operator)) { continue; } isValid = true; } } // 无法生成不重复的题目 if (!isValid) { isValid = true; switch (operator) { case '+': num1 = getRandomNumber(min, max); num2 = getRandomNumber(min, max); answer = num1 + num2; case '-': // 确保结果为正数且不是0 num1 = getRandomNumber(min, max); num2 = getRandomNumber(min, max); if (num1 < num2) { [num1, num2] = [num2, num1]; } answer = num1 - num2; case '×': // 限制乘法结果不超过1000且避免简单乘法 num1 = getRandomNumber(2, max / 2); num2 = getRandomNumber(2, max / num1); answer = num1 * num2; case '÷': // 生成除法题目,确保能整除且除数不是1 // 生成一个除数(确保不是1) num2 = getRandomNumber(2, max / 2); // 生成一个除数(确保不是1) answer = getRandomNumber(2, max / num2); // 计算被除数 num1 = answer * num2; } } if (isValid) { newQuestions.push({ id: newQuestions.length + 1, num1, num2, operator, answer, userAnswer: null, isCorrect: false }); } } }); // 打乱题目顺序 return newQuestions //.sort(() => Math.random() - 0.5).map((q, i) => ({...q, id: i + 1})); } // 渲染题目 function renderQuestions(questions) { questionsContainer.innerHTML = ''; questions.forEach(question => { const questionEl = document.createElement('div'); questionEl.className = 'question-item'; questionEl.innerHTML = ` <div class="question-number">${question.id}.</div> <div class="question-text">${question.num1} ${question.operator} ${question.num2} = </div> <input type="number" class="question-answer" id="answer-${question.id}" data-id="${question.id}" placeholder="?" min="0" max="999"> `; questionsContainer.appendChild(questionEl); }); // 添加输入事件监听器 document.querySelectorAll('.question-answer').forEach(input => { input.addEventListener('input', function() { const id = parseInt(this.dataset.id); const value = this.value.trim(); if (value === '') { delete userAnswers[id]; this.classList.remove('correct', 'incorrect'); } else { const numValue = parseInt(value); userAnswers[id] = numValue; } // 更新统计信息 updateStats(); }); // 允许使用键盘方向键在输入框之间导航 input.addEventListener('keydown', function(e) { if (e.key === 'Enter') { e.preventDefault(); const nextInput = this.parentElement.nextElementSibling?.querySelector('.question-answer'); if (nextInput) { nextInput.focus(); } } // Ctrl+Enter 提交答案 if (e.ctrlKey && e.key === 'Enter') { e.preventDefault(); if (isTestActive) { finishTest(); } } }); }); } // 更新统计信息 function updateStats() { let answered = 0; let correct = 0; questions.forEach(question => { if (userAnswers[question.id] !== undefined) { answered++; if (userAnswers[question.id] === question.answer) { correct++; } } }); const total = questions.length; const remaining = total - answered; answeredCountEl.textContent = answered; remainingCountEl.textContent = remaining; } // 开始测试 function startTest() { const questionCount = parseInt(questionCountInput.value) || 40; timeLeft = parseInt(timeLimitInput.value) || 180; // 生成题目 questions = generateQuestions(questionCount); userAnswers = {}; // 渲染题目 renderQuestions(questions); // 显示题目区域和统计面板,隐藏结果区域 questionsWrapper.classList.remove('hidden'); statsPanel.classList.remove('hidden'); resultContainer.style.display = 'none'; // 显示提交按钮,隐藏开始按钮 startBtn.classList.add('hidden'); submitBtn.classList.remove('hidden'); // 开始计时 startTime = Date.now(); isTestActive = true; updateTimerDisplay(); // 初始化统计信息 updateStats(); timer = setInterval(() => { timeLeft--; updateTimerDisplay(); if (timeLeft <= 0) { finishTest(); } }, 1000); } // 更新计时器显示 function updateTimerDisplay() { const minutes = Math.floor(timeLeft / 60); const seconds = timeLeft % 60; timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; // 时间少于30秒时改变颜色 if (timeLeft < 30) { timerDisplay.style.color = '#e74c3c'; timerDisplay.style.backgroundColor = '#fef5f5'; } else if (timeLeft < 60) { timerDisplay.style.color = '#f39c12'; timerDisplay.style.backgroundColor = '#fef9e7'; } else { timerDisplay.style.color = '#3498db'; timerDisplay.style.backgroundColor = '#f5fafe'; } } // 完成测试 function finishTest() { clearInterval(timer); isTestActive = false; // 计算得分 let correctCount = 0; let errorCount = 0; let unansweredCount = 0; questions.forEach(question => { const userAnswer = userAnswers[question.id]; question.userAnswer = userAnswer; if (userAnswer === undefined || userAnswer === null) { unansweredCount++; } else if (userAnswer === question.answer) { correctCount++; question.isCorrect = true; } else { errorCount++; question.isCorrect = false; } }); // 计算用时 const endTime = Date.now(); const timeUsedMs = endTime - startTime; const timeUsedSeconds = Math.floor(timeUsedMs / 1000); const minutesUsed = Math.floor(timeUsedSeconds / 60); const secondsUsed = timeUsedSeconds % 60; // 显示结果 questionsWrapper.classList.add('hidden'); statsPanel.classList.add('hidden'); resultContainer.style.display = 'block'; totalQuestionsEl.textContent = questions.length; timeUsedEl.textContent = `${minutesUsed.toString().padStart(2, '0')}:${secondsUsed.toString().padStart(2, '0')}`; resultScore.textContent = `${correctCount}/${questions.length}`; // 显示错误数量信息 if (errorCount > 0) { errorCountInfo.textContent = `错了 ${errorCount} 道题 `; resultScore.classList.add('result-fail'); // 根据正确率显示不同信息 const accuracy = (correctCount / questions.length) * 100; if (accuracy >= 90) { resultMessage.textContent = "非常接近完美!再仔细一点就能全部答对了!"; } else if (accuracy >= 70) { resultMessage.textContent = "表现不错!继续努力,下次会更好!"; } else { resultMessage.textContent = "需要多加练习哦,继续加油!"; } resultMessage.style.color = "#e74c3c"; } if (unansweredCount > 0) { emptyCountInfo.textContent = `有 ${unansweredCount} 道题未作答 `; resultScore.classList.add('result-fail'); resultMessage.textContent = "有些题目还没完成哦。"; resultMessage.style.color = "#f39c12"; } if (correctCount === questions.length) { errorCountInfo.textContent = ""; resultScore.classList.remove('result-fail'); resultMessage.textContent = "恭喜!全部答对了!你是数学小天才!🎉"; resultMessage.style.color = "#2ecc71"; } // 显示开始按钮,隐藏提交按钮 startBtn.classList.remove('hidden'); submitBtn.classList.add('hidden'); } // 事件监听器 startBtn.addEventListener('click', startTest); submitBtn.addEventListener('click', function() { if (isTestActive) { if (confirm('确定要提前提交答案吗?')) { finishTest(); } } }); // 初始加载时显示开始按钮 window.addEventListener('DOMContentLoaded', () => { startBtn.classList.remove('hidden'); submitBtn.classList.add('hidden'); // 生成示例题目(确保没有除以1的情况) let sampleQuestion; let attempts = 0; do { sampleQuestion = generateQuestions(1)[0]; attempts++; // 防止无限循环 if (attempts > 10) break; } while (sampleQuestion.operator === '÷' && (sampleQuestion.num2 === 1 || sampleQuestion.answer === 1)); const sampleEl = document.createElement('p'); sampleEl.className = 'description'; sampleEl.style.marginTop = '10px'; sampleEl.innerHTML = `示例题目: ${sampleQuestion.num1} ${sampleQuestion.operator} ${sampleQuestion.num2} = <span style="color:#3498db; font-weight:bold">${sampleQuestion.answer}</span>`; document.querySelector('header').appendChild(sampleEl); }); // 添加键盘快捷键支持 document.addEventListener('keydown', function(e) { // 空格键开始/重新开始 if (e.code === 'Space' && !isTestActive) { e.preventDefault(); startTest(); } }); // 输入框限制:只允许输入数字 document.addEventListener('input', function(e) { if (e.target.classList.contains('question-answer')) { // 移除非数字字符 e.target.value = e.target.value.replace(/[^\d]/g, ''); // 限制最大值 if (e.target.value.length > 3) { e.target.value = e.target.value.slice(0, 3); } } }); </script> </body> </html>

创建于 2025/12/8

更新于 2025/12/8