[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小学生数学题生成器</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
display: block;
flex-direction: column;
align-items: center;
justify-content: center;
}
#options {
display: block;
margin: 20px auto;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 20px;
box-sizing: border-box;
width: 500px;
line-height: 35px;
}
label {
margin-right: 10px;
margin-bottom: 10px;
font-size: 16px;
}
button {
padding: 5px;
background-color: #4caf50;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
}
#questions {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 20px;
}
.question {
width: 48%;
box-sizing: border-box;
padding: 10px;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
font-size: 18px;
}
.answer {
display: none;
font-size: 16px;
}
#printHeader {
display: none;
margin-bottom: 20px;
}
[url=home.php?mod=space&uid=945662]@media[/url] print {
#printHeader {
display: block;
text-align: center;
margin-bottom: 30px;
}
body {
margin: 30px;
}
.column {
display: inline-block;
width: 24%;
box-sizing: border-box;
margin-bottom: 20px;
vertical-align: top;
}
.question {
page-break-inside: avoid;
width: 100%;
margin-bottom: 8px;
font-size: 16px;
padding: 5px;
}
[url=home.php?mod=space&uid=1953840]@page[/url] {
size: A4;
margin: 25mm 10mm 25mm 10mm;
}
.page {
page-break-after: always;
}
.page:not(:first-child) #printHeader {
display: none;
}
}
div#printHeader {
text-align: center;
margin-bottom: 15px;
}
.hole-type-options {
display: none;
margin-top: 10px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="hd1" style="text-align:center;font-size:35px;background-color: #4CAF50;min-height: 100px;padding-top: 50px;"><font>小学生数学题生成器</font></div>
<div id="options">
<label>
题目类型:
<select id="questionType">
<option value="normal">普通类型</option>
<option value="hole">挖空类型</option>
<option value="compare">比大小类型</option>
</select>
</label>
<br>
<div id="normalOptions">
运算符号:
<label>
<input type="checkbox" id="additionCheckbox" checked="checked"> 加法
</label>
<label>
<input type="checkbox" id="subtractionCheckbox"> 减法
</label>
<label>
<input type="checkbox" id="multiplicationCheckbox"> 乘法
</label>
<label>
<input type="checkbox" id="divisionCheckbox"> 除法
</label>
<br>
</div>
<div id="holeTypeOptions" class="hole-type-options">
<label>
挖空位置:
<select id="holePosition">
<option value="random">随机</option>
<option value="left">左边挖空</option>
<option value="right">右边挖空</option>
</select>
</label>
<br>
<small>注:挖空类型仅支持加法和减法</small>
</div>
<div id="compareTypeOptions" class="hole-type-options">
<label>
比大小类型:
<select id="compareType">
<option value="normal">普通比大小</option>
<option value="hole">挖空比大小</option>
</select>
</label>
<br>
<label>
运算符号:
<select id="compareOperator">
<option value="add">加法</option>
<option value="sub">减法</option>
<option value="random">随机</option>
</select>
</label>
<br>
<label>
挖空位置(仅挖空比大小):
<select id="compareHolePosition">
<option value="random">随机</option>
<option value="left">左边挖空</option>
<option value="right">右边挖空</option>
</select>
</label>
<br>
<small>注:比大小类型需要2个数字</small>
</div>
<label>
数字个数:<input type="number" id="numOfDigits" value="2" min="1" style="width: 50px;">
</label> <br>
<label>
允许小数:<input type="checkbox" id="allowDecimal">
</label>
<br>
<div id="numberRanges"></div>
<br>
<label>
结果最大值:<input type="number" id="maxResult" value="100" min="1" style="width: 50px;">
</label>
<br>
<label>
出题数量:<input type="number" id="numOfQuestions" value="100" min="1" style="width: 50px;">
</label>
<br>
<button>生成题目</button>
<button>一键打印</button>
<button>显示/隐藏答案</button>
</div>
<div id="questions"></div>
<script>
// 动态生成每个数的范围输入框
const numOfDigitsInput = document.getElementById('numOfDigits');
const numberRangesDiv = document.getElementById('numberRanges');
function updateNumberRanges() {
const numOfDigits = parseInt(numOfDigitsInput.value);
numberRangesDiv.innerHTML = '';
for (let i = 1; i <= numOfDigits; i++) {
const rangeLabel = document.createElement('label');
rangeLabel.textContent = `第 ${i} 个数的范围:`;
const minInput = document.createElement('input');
minInput.type = 'number';
minInput.id = `minRange${i}`;
minInput.value = 1;
minInput.min = 1;
minInput.style.width = '50px';
const dashLabel = document.createElement('label');
dashLabel.textContent = '-';
const maxInput = document.createElement('input');
maxInput.type = 'number';
maxInput.id = `maxRange${i}`;
maxInput.value = 100;
maxInput.min = 1;
maxInput.style.width = '50px';
rangeLabel.appendChild(minInput);
rangeLabel.appendChild(dashLabel);
rangeLabel.appendChild(maxInput);
numberRangesDiv.appendChild(rangeLabel);
numberRangesDiv.appendChild(document.createElement('br'));
}
}
numOfDigitsInput.addEventListener('input', updateNumberRanges);
updateNumberRanges();
function toggleQuestionType() {
const questionType = document.getElementById('questionType').value;
const normalOptions = document.getElementById('normalOptions');
const holeTypeOptions = document.getElementById('holeTypeOptions');
const compareTypeOptions = document.getElementById('compareTypeOptions');
if (questionType === 'hole') {
normalOptions.style.display = 'none';
holeTypeOptions.style.display = 'block';
compareTypeOptions.style.display = 'none';
// 强制勾选加法和减法
document.getElementById('additionCheckbox').checked = true;
document.getElementById('subtractionCheckbox').checked = true;
document.getElementById('multiplicationCheckbox').checked = false;
document.getElementById('divisionCheckbox').checked = false;
// 挖空类型需要4个数字
document.getElementById('numOfDigits').value = 4;
updateNumberRanges();
} else if (questionType === 'compare') {
normalOptions.style.display = 'none';
holeTypeOptions.style.display = 'none';
compareTypeOptions.style.display = 'block';
// 比大小类型需要2个数字
document.getElementById('numOfDigits').value = 2;
updateNumberRanges();
} else {
normalOptions.style.display = 'block';
holeTypeOptions.style.display = 'none';
compareTypeOptions.style.display = 'none';
}
}
function checkIntermediateResults(numbers, operators, allowDecimal) {
const nums = numbers.map(num => parseFloat(num));
const ops = operators.map(op => op);
// 处理乘除法,因为它们的优先级高于加减法
for (let i = 0; i < ops.length; i++) {
if (ops[i] === '*' || ops[i] === '/') {
const result = ops[i] === '*' ? nums[i] * nums[i + 1] : nums[i] / nums[i + 1];
nums.splice(i, 2, result);
ops.splice(i, 1);
i--;
}
}
// 处理加减法,检查每一步的结果是否非负
let result = nums[0];
for (let i = 0; i < ops.length; i++) {
const num = nums[i + 1];
const operator = ops[i];
if (operator === '-') {
if (result < num) {
return false;
}
result -= num;
} else if (operator === '+') {
result += num;
}
}
return true;
}
function generateQuestions() {
const questionType = document.getElementById('questionType').value;
const addition = document.getElementById("additionCheckbox").checked;
const subtraction = document.getElementById("subtractionCheckbox").checked;
const multiplication = document.getElementById("multiplicationCheckbox").checked;
const division = document.getElementById("divisionCheckbox").checked;
const numOfDigits = parseInt(document.getElementById("numOfDigits").value);
const allowDecimal = document.getElementById("allowDecimal").checked;
const numOfQuestions = document.getElementById("numOfQuestions").value;
const maxResult = parseInt(document.getElementById("maxResult").value);
const questionsContainer = document.getElementById("questions");
questionsContainer.innerHTML = "";
for (let i = 0; i < numOfQuestions; i++) {
let validQuestion = false;
let questionText, answerText;
while (!validQuestion) {
if (questionType === 'hole') {
// 挖空类型逻辑
const holePosition = document.getElementById('holePosition').value;
const actualHolePosition = holePosition === 'random'
? (Math.random() < 0.5 ? 'left' : 'right')
: holePosition;
const result = generateHoleQuestion(actualHolePosition, allowDecimal, maxResult, numOfDigits);
if (result) {
questionText = result.questionText;
answerText = result.answerText;
// 确保答案不是负数
if (parseFloat(answerText) >= 0) {
validQuestion = true;
}
}
} else if (questionType === 'compare') {
// 比大小类型逻辑
const compareType = document.getElementById('compareType').value;
const compareOperator = document.getElementById('compareOperator').value;
const compareHolePosition = document.getElementById('compareHolePosition').value;
const result = generateCompareQuestion(compareType, compareOperator, compareHolePosition, allowDecimal, maxResult, numOfDigits);
if (result) {
questionText = result.questionText;
answerText = result.answerText;
validQuestion = true;
}
} else {
// 普通类型逻辑
const operators = getRandomOperators(addition, subtraction, multiplication, division, numOfDigits);
const numbers = generateNumbers(numOfDigits, allowDecimal);
questionText = generateQuestionText(numbers, operators, allowDecimal);
answerText = calculateAnswer(numbers, operators, allowDecimal).toFixed(allowDecimal ? 2 : 0);
// 确保没有负数且结果在范围内,并且中间结果都非负
if (!containsNegativeNumber(questionText) && answerText >= 0 && parseFloat(answerText) <= maxResult && checkIntermediateResults(numbers, operators, allowDecimal)) {
validQuestion = true;
}
}
}
const questionDiv = document.createElement("div");
questionDiv.classList.add("question");
questionDiv.innerHTML = `<span>${questionText}</span><span class="answer">${parseFloat(answerText)}</span>`;
questionsContainer.appendChild(questionDiv);
}
}
function generateHoleQuestion(holePosition, allowDecimal, maxResult, numOfDigits) {
// 挖空类型需要4个数字
if (numOfDigits !== 4) {
alert("挖空类型需要4个数字,请将数字个数设置为4");
return null;
}
// 生成4个数字
const numbers = generateNumbers(numOfDigits, allowDecimal);
const left1 = parseFloat(numbers[0]);
const left2 = parseFloat(numbers[1]);
const right1 = parseFloat(numbers[2]);
const right2 = parseFloat(numbers[3]);
// 随机选择加法或减法
const operators = ['+', '-'];
const leftOperator = operators[Math.floor(Math.random() * operators.length)];
const rightOperator = operators[Math.floor(Math.random() * operators.length)];
// 计算左右两边结果
let leftResult, rightResult;
// 计算左边结果
if (leftOperator === '+') {
leftResult = left1 + left2;
} else {
// 确保减法结果不为负数
if (left1 < left2) {
// 如果第一个数小于第二个数,交换它们的位置
numbers[0] = left2;
numbers[1] = left1;
leftResult = left2 - left1;
} else {
leftResult = left1 - left2;
}
}
// 计算右边结果
if (rightOperator === '+') {
rightResult = right1 + right2;
} else {
// 确保减法结果不为负数
if (right1 < right2) {
// 如果第一个数小于第二个数,交换它们的位置
numbers[2] = right2;
numbers[3] = right1;
rightResult = right2 - right1;
} else {
rightResult = right1 - right2;
}
}
// 确保两边结果相等且在合理范围内
if (leftResult !== rightResult || leftResult < 0 || leftResult > maxResult) {
return null;
}
let questionText, answerText;
if (holePosition === 'left') {
// 左边挖空一个数
const holeIndex = Math.random() < 0.5 ? 0 : 1;
const holeNumber = holeIndex === 0 ? numbers[0] : numbers[1];
if (holeIndex === 0) {
questionText = `(____ ${leftOperator} ${formatNumber(numbers[1], allowDecimal)}) = (${formatNumber(numbers[2], allowDecimal)} ${rightOperator} ${formatNumber(numbers[3], allowDecimal)})`;
} else {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${leftOperator} ____) = (${formatNumber(numbers[2], allowDecimal)} ${rightOperator} ${formatNumber(numbers[3], allowDecimal)})`;
}
answerText = holeNumber;
} else {
// 右边挖空一个数
const holeIndex = Math.random() < 0.5 ? 2 : 3;
const holeNumber = holeIndex === 2 ? numbers[2] : numbers[3];
if (holeIndex === 2) {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${leftOperator} ${formatNumber(numbers[1], allowDecimal)}) = (____ ${rightOperator} ${formatNumber(numbers[3], allowDecimal)})`;
} else {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${leftOperator} ${formatNumber(numbers[1], allowDecimal)}) = (${formatNumber(numbers[2], allowDecimal)} ${rightOperator} ____)`;
}
answerText = holeNumber;
}
return { questionText, answerText };
}
function generateCompareQuestion(compareType, compareOperator, compareHolePosition, allowDecimal, maxResult, numOfDigits) {
// 比大小类型需要2个数字
if (numOfDigits !== 2) {
alert("比大小类型需要2个数字,请将数字个数设置为2");
return null;
}
// 生成4个数字(左边2个,右边2个)
const numbers = generateNumbers(4, allowDecimal);
const left1 = parseFloat(numbers[0]);
const left2 = parseFloat(numbers[1]);
const right1 = parseFloat(numbers[2]);
const right2 = parseFloat(numbers[3]);
// 确定运算符
let operator;
if (compareOperator === 'random') {
operator = Math.random() < 0.5 ? '+' : '-';
} else {
operator = compareOperator === 'add' ? '+' : '-';
}
// 计算左右两边结果
let leftResult, rightResult;
// 计算左边结果
if (operator === '+') {
leftResult = left1 + left2;
} else {
// 确保减法结果不为负数
if (left1 < left2) {
numbers[0] = left2;
numbers[1] = left1;
leftResult = left2 - left1;
} else {
leftResult = left1 - left2;
}
}
// 计算右边结果
if (operator === '+') {
rightResult = right1 + right2;
} else {
// 确保减法结果不为负数
if (right1 < right2) {
numbers[2] = right2;
numbers[3] = right1;
rightResult = right2 - right1;
} else {
rightResult = right1 - right2;
}
}
// 确保两边结果在合理范围内
if (leftResult < 0 || leftResult > maxResult || rightResult < 0 || rightResult > maxResult) {
return null;
}
// 确定比较符号
let compareSymbol;
if (leftResult > rightResult) {
compareSymbol = '>';
} else if (leftResult < rightResult) {
compareSymbol = '<';
} else {
compareSymbol = '=';
}
let questionText, answerText;
if (compareType === 'normal') {
// 普通比大小
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${operator} ${formatNumber(numbers[1], allowDecimal)}) ${compareSymbol} (${formatNumber(numbers[2], allowDecimal)} ${operator} ${formatNumber(numbers[3], allowDecimal)})`;
answerText = `${leftResult} ${compareSymbol} ${rightResult}`;
} else {
// 挖空比大小
let actualHolePosition = compareHolePosition;
if (compareHolePosition === 'random') {
actualHolePosition = Math.random() < 0.5 ? 'left' : 'right';
}
if (actualHolePosition === 'left') {
// 左边挖空一个数
const holeIndex = Math.random() < 0.5 ? 0 : 1;
const holeNumber = holeIndex === 0 ? numbers[0] : numbers[1];
if (holeIndex === 0) {
questionText = `(____ ${operator} ${formatNumber(numbers[1], allowDecimal)}) ${compareSymbol} (${formatNumber(numbers[2], allowDecimal)} ${operator} ${formatNumber(numbers[3], allowDecimal)})`;
} else {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${operator} ____) ${compareSymbol} (${formatNumber(numbers[2], allowDecimal)} ${operator} ${formatNumber(numbers[3], allowDecimal)})`;
}
answerText = holeNumber;
} else {
// 右边挖空一个数
const holeIndex = Math.random() < 0.5 ? 2 : 3;
const holeNumber = holeIndex === 2 ? numbers[2] : numbers[3];
if (holeIndex === 2) {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${operator} ${formatNumber(numbers[1], allowDecimal)}) ${compareSymbol} (____ ${operator} ${formatNumber(numbers[3], allowDecimal)})`;
} else {
questionText = `(${formatNumber(numbers[0], allowDecimal)} ${operator} ${formatNumber(numbers[1], allowDecimal)}) ${compareSymbol} (${formatNumber(numbers[2], allowDecimal)} ${operator} ____)`;
}
answerText = holeNumber;
}
}
return { questionText, answerText };
}
function generateRandomNumber(min, max, allowDecimal) {
if (allowDecimal) {
return parseFloat((Math.random() * (max - min) + min).toFixed(2));
} else {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
function formatNumber(num, allowDecimal) {
return allowDecimal ? parseFloat(num).toFixed(2) : parseInt(num);
}
function getRandomOperators(addition, subtraction, multiplication, division, numOfDigits) {
const availableOperators = [];
if (addition) availableOperators.push('+');
if (subtraction) availableOperators.push('-');
if (multiplication && numOfDigits >= 2) availableOperators.push('*');
if (division && numOfDigits >= 2) availableOperators.push('/');
const selectedOperators = [];
for (let i = 0; i < numOfDigits - 1; i++) {
const randomOperator = availableOperators[Math.floor(Math.random() * availableOperators.length)];
selectedOperators.push(randomOperator);
}
return selectedOperators;
}
function generateQuestionText(numbers, operators, allowDecimal) {
let questionText = numbers[0].toString();
for (let i = 0; i < operators.length; i++) {
const operator = operators[i];
const num = allowDecimal ? parseFloat(numbers[i + 1]).toFixed(2) : parseInt(numbers[i + 1]);
questionText += ` ${operator.replace('*', 'x').replace('/', '÷')} ${num}`;
}
questionText += ' =';
return questionText;
}
function generateNumbers(numOfDigits, allowDecimal) {
const numbers = [];
for (let i = 1; i <= numOfDigits; i++) {
const minRange = parseInt(document.getElementById(`minRange${i}`).value);
const maxRange = parseInt(document.getElementById(`maxRange${i}`).value);
const randomNumber = () => allowDecimal
? (Math.random() * (maxRange - minRange) + minRange).toFixed(2)
: Math.floor(Math.random() * (maxRange - minRange + 1)) + minRange;
numbers.push(randomNumber());
}
return numbers;
}
function calculateAnswer(numbers, operators, allowDecimal) {
const calculateMulDiv = (nums, ops) => {
for (let i = 0; i < ops.length; i++) {
if (ops[i] === '*' || ops[i] === '/') {
const result = ops[i] === '*' ? nums[i] * nums[i + 1] : nums[i] / nums[i + 1];
nums.splice(i, 2, result);
ops.splice(i, 1);
i--;
}
}
};
const nums = numbers.map(num => parseFloat(num));
const ops = operators.map(op => op);
calculateMulDiv(nums, ops);
let result = nums[0];
for (let i = 0; i < ops.length; i++) {
const num = nums[i + 1];
const operator = ops[i];
switch (operator) {
case '+':
result += num;
break;
case '-':
result -= num;
break;
default:
break;
}
}
return allowDecimal
? parseFloat(result.toFixed(2))
: parseInt(result);
}
function containsNegativeNumber(questionText) {
const parts = questionText.split(' ');
for (let i = 0; i < parts.length; i++) {
if (parseFloat(parts[i]) < 0) {
return true;
}
}
return false;
}
function printQuestions() {
const printWindow = window.open('', '_blank');
const questions = document.querySelectorAll('.question');
// 获取当前日期字符串
function getCurrentDateString() {
const now = new Date();
const month = now.getMonth() + 1;
const day = now.getDate();
return `${month}月${day}日`;
}
// 每页100题(4列 x 25题/列)
const questionsPerPage = 100;
const totalPages = Math.ceil(questions.length / questionsPerPage);
let printContent = '';
for (let page = 0; page < totalPages; page++) {
printContent += `
<div class="page">
<div id="printHeader" style="text-align: center;margin-bottom: 20px;">
<div>姓名:_________ 日期:${getCurrentDateString()} 时间:________ 答对:_______题</div>
</div>
<div class="column" id="column${page * 4 + 1}"></div>
<div class="column" id="column${page * 4 + 2}"></div>
<div class="column" id="column${page * 4 + 3}"></div>
<div class="column" id="column${page * 4 + 4}"></div>
</div>
`;
}
printWindow.document.write(`
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打印题目</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 30px;
}
.column {
display: inline-block;
width: 24%;
box-sizing: border-box;
margin-bottom: 20px;
vertical-align: top;
}
.question {
padding: 5px;
background-color: #fff;
border-radius: 3px;
margin-bottom: 8px;
font-size: 16px;
}
.answer {
display: none;
font-size: 14px;
}
.page {
page-break-after: always;
}
.page:not(:first-child) #printHeader {
display: none;
}
</style>
</head>
<body>
${printContent}
</body>
</html>
`);
questions.forEach((question, index) => {
const pageIndex = Math.floor(index / questionsPerPage);
const columnIndex = Math.floor((index % questionsPerPage) / 25);
const columnId = `column${pageIndex * 4 + columnIndex + 1}`;
const column = printWindow.document.getElementById(columnId);
const clonedQuestion = question.cloneNode(true);
// Replace answer content with formatted answer
const answerElement = clonedQuestion.querySelector('.answer');
const answerText = answerElement.textContent;
answerElement.textContent = parseFloat(answerText).toFixed(2);
column.appendChild(clonedQuestion);
});
printWindow.document.close();
printWindow.print();
}
function toggleAnswers() {
const answers = document.querySelectorAll('.answer');
answers.forEach(answer => {
answer.style.display = (answer.style.display === 'none' || answer.style.display === '') ? 'inline' : 'none';
});
}
</script>
</body>
</html>