<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>随机数生成器</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: rgba(255,255,255,0.95);
border-radius: 24px;
padding: 30px 25px;
width: 100%;
max-width: 420px;
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
text-align: center;
}
h1 {
font-size: 24px;
color: #333;
margin-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.range-group {
display: flex;
justify-content: space-between;
gap: 12px;
margin-bottom: 20px;
}
.range-item {
flex: 1;
text-align: left;
}
.range-item label {
font-size: 14px;
color: #555;
display: block;
margin-bottom: 6px;
}
.range-item input {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-radius: 12px;
font-size: 18px;
text-align: center;
outline: none;
transition: border-color 0.3s;
background: #f9f9f9;
}
.range-item input:focus {
border-color: #764ba2;
background: #fff;
}
.result-box {
background: #f0f0f0;
border-radius: 16px;
padding: 30px 20px;
margin: 20px 0;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
border: 2px dashed #ccc;
}
.result-number {
font-size: 56px;
font-weight: 800;
color: #764ba2;
line-height: 1.2;
word-break: break-all;
}
.result-placeholder {
color: #aaa;
font-size: 18px;
}
.btn-group {
display: flex;
gap: 12px;
margin-bottom: 20px;
}
.btn {
flex: 1;
padding: 14px;
border: none;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn:active {
transform: scale(0.96);
}
.btn-primary {
background: #764ba2;
color: #fff;
box-shadow: 0 4px 10px rgba(118,75,162,0.4);
}
.btn-secondary {
background: #eee;
color: #555;
}
.btn-copy {
background: #4caf50;
color: #fff;
box-shadow: 0 4px 10px rgba(76,175,80,0.3);
}
.history-section {
margin-top: 10px;
text-align: left;
}
.history-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.history-header h3 {
font-size: 16px;
color: #333;
}
.clear-btn {
background: none;
border: none;
color: #e74c3c;
font-size: 14px;
cursor: pointer;
text-decoration: underline;
}
.history-list {
max-height: 150px;
overflow-y: auto;
background: #fafafa;
border-radius: 12px;
padding: 10px;
border: 1px solid #eee;
}
.history-item {
display: flex;
justify-content: space-between;
padding: 6px 8px;
border-radius: 8px;
font-size: 14px;
color: #444;
}
.history-item:nth-child(odd) {
background: #f0f0f0;
}
.history-item span:first-child {
color: #999;
}
.history-item span:last-child {
font-weight: 600;
color: #764ba2;
}
.toast {
position: fixed;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
background: #333;
color: #fff;
padding: 10px 20px;
border-radius: 20px;
font-size: 14px;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
z-index: 100;
}
.toast.show {
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<h1>🎲 随机数生成器</h1>
<div class="range-group">
<div class="range-item">
<label>最小值</label>
<input type="number" id="minInput" value="1">
</div>
<div class="range-item">
<label>最大值</label>
<input type="number" id="maxInput" value="100">
</div>
</div>
<div class="result-box" id="resultBox">
<div class="result-placeholder" id="placeholder">点击生成</div>
<div class="result-number" id="resultNumber" style="display:none;"></div>
</div>
<div class="btn-group">
<button class="btn btn-primary" id="generateBtn">生成</button>
<button class="btn btn-copy" id="copyBtn">复制</button>
</div>
<div class="history-section">
<div class="history-header">
<h3>📜 历史记录</h3>
<button class="clear-btn" id="clearBtn">清空</button>
</div>
<div class="history-list" id="historyList">
<div style="color:#aaa; text-align:center; padding:10px; font-size:14px;">暂无记录</div>
</div>
</div>
</div>
<div class="toast" id="toast"></div>
<script>
(function() {
const minInput = document.getElementById('minInput');
const maxInput = document.getElementById('maxInput');
const resultNumber = document.getElementById('resultNumber');
const placeholder = document.getElementById('placeholder');
const generateBtn = document.getElementById('generateBtn');
const copyBtn = document.getElementById('copyBtn');
const clearBtn = document.getElementById('clearBtn');
const historyList = document.getElementById('historyList');
const toast = document.getElementById('toast');
let history = [];
// 初始化历史记录
try {
const saved = localStorage.getItem('randomHistory');
if (saved) history = JSON.parse(saved);
} catch(e) {}
renderHistory();
function generateRandom() {
let min = parseInt(minInput.value, 10);
let max = parseInt(maxInput.value, 10);
// 处理无效输入
if (isNaN(min)) min = 1;
if (isNaN(max)) max = 100;
if (min > max) {
const temp = min;
min = max;
max = temp;
minInput.value = min;
maxInput.value = max;
}
const range = max - min + 1;
const random = Math.floor(Math.random() * range) + min;
// 显示结果
resultNumber.textContent = random;
resultNumber.style.display = 'block';
placeholder.style.display = 'none';
// 添加到历史
const now = new Date();
const timeStr = now.getHours().toString().padStart(2,'0') + ':' + now.getMinutes().toString().padStart(2,'0') + ':' + now.getSeconds().toString().padStart(2,'0');
history.unshift({ value: random, time: timeStr });
if (history.length > 20) history.pop();
localStorage.setItem('randomHistory', JSON.stringify(history));
renderHistory();
return random;
}
function renderHistory() {
if (history.length === 0) {
historyList.innerHTML = '<div style="color:#aaa; text-align:center; padding:10px; font-size:14px;">暂无记录</div>';
return;
}
historyList.innerHTML = history.map((item, index) => `
<div class="history-item">
<span>${item.time}</span>
<span>${item.value}</span>
</div>
`).join('');
}
function showToast(msg) {
toast.textContent = msg;
toast.classList.add('show');
setTimeout(() => toast.classList.remove('show'), 1500);
}
// 事件绑定
generateBtn.addEventListener('click', generateRandom);
copyBtn.addEventListener('click', function() {
const val = resultNumber.textContent;
if (!val) {
showToast('请先生成一个数字');
return;
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(val).then(() => {
showToast('已复制 ' + val);
}).catch(() => {
// 降级方案
fallbackCopy(val);
});
} else {
fallbackCopy(val);
}
});
function fallbackCopy(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
showToast('已复制 ' + text);
} catch(e) {
showToast('复制失败,请手动复制');
}
document.body.removeChild(textarea);
}
clearBtn.addEventListener('click', function() {
history = [];
localStorage.removeItem('randomHistory');
renderHistory();
showToast('历史已清空');
});
// 键盘支持
document.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
generateRandom();
}
if (e.key === 'c' || e.key === 'C') {
copyBtn.click();
}
});
// 初始生成一个数字
generateRandom();
})();
</script>
</body>
</html>