JavaScript定时器
我将设计一个直观的定时器管理界面,帮助用户创建、监控和清理定时器。定时器的界面如下所示,你可以将代码复制保存为html,再用浏览器打开。
设计思路
- 创建清晰的UI来添加定时器
- 实时显示所有活动定时器的状态
- 提供批量清理和单独清理功能
- 添加可视化效果增强用户体验
功能说明
这个定时器管理工具提供以下功能:
-
创建定时器:
- 选择setTimeout(一次性)或setInterval(重复执行)
- 设置定时器持续时间(毫秒)
- 添加自定义消息
-
监控定时器:
- 实时显示所有活动定时器
- 显示定时器类型、持续时间和消息
- 进度条可视化定时器执行进度
-
清理定时器:
- 单独清理每个定时器
- 批量清理所有活动定时器
-
统计信息:
- 显示活动定时器数量
- 显示已清理定时器数量
- 显示总定时器数量
这个工具不仅实用,而且具有美观的界面和流畅的交互体验,帮助开发者更好地管理和调试JavaScript定时器。
最终实现代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript定时器管理工具</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
color: #fff;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1000px;
margin: 0 auto;
background: rgba(0, 0, 0, 0.7);
border-radius: 15px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
header {
text-align: center;
margin-bottom: 30px;
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.subtitle {
font-size: 1.2rem;
opacity: 0.8;
}
.timer-controls {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 30px;
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 10px;
}
.control-group {
flex: 1;
min-width: 200px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
}
input, select, button {
width: 100%;
padding: 12px;
border: none;
border-radius: 5px;
font-size: 1rem;
}
input, select {
background: rgba(255, 255, 255, 0.9);
}
button {
background: #4CAF50;
color: white;
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
margin-top: 20px;
}
button:hover {
background: #45a049;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.danger-btn {
background: #f44336;
}
.danger-btn:hover {
background: #d32f2f;
}
.timer-list {
margin-top: 20px;
}
.timer-item {
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(255, 255, 255, 0.1);
padding: 15px;
margin-bottom: 10px;
border-radius: 8px;
transition: all 0.3s;
}
.timer-item:hover {
background: rgba(255, 255, 255, 0.15);
transform: translateX(5px);
}
.timer-info {
flex: 1;
}
.timer-id {
font-weight: bold;
font-size: 1.1rem;
}
.timer-details {
display: flex;
gap: 15px;
margin-top: 5px;
font-size: 0.9rem;
opacity: 0.8;
}
.timer-actions {
display: flex;
gap: 10px;
}
.timer-actions button {
margin: 0;
padding: 8px 15px;
width: auto;
}
.status {
padding: 5px 10px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: bold;
}
.status-active {
background: #4CAF50;
}
.status-cleared {
background: #f44336;
}
.stats {
display: flex;
justify-content: space-between;
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid rgba(255, 255, 255, 0.2);
}
.stat-box {
text-align: center;
flex: 1;
}
.stat-value {
font-size: 2rem;
font-weight: bold;
margin-bottom: 5px;
}
.stat-label {
font-size: 0.9rem;
opacity: 0.8;
}
.empty-state {
text-align: center;
padding: 40px;
opacity: 0.7;
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.progress-bar {
height: 5px;
background: rgba(255, 255, 255, 0.2);
border-radius: 5px;
margin-top: 10px;
overflow: hidden;
}
.progress {
height: 100%;
background: #4CAF50;
width: 0%;
transition: width 0.5s;
}
@media (max-width: 768px) {
.timer-controls {
flex-direction: column;
}
.timer-item {
flex-direction: column;
align-items: flex-start;
}
.timer-actions {
margin-top: 10px;
width: 100%;
}
.timer-actions button {
flex: 1;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>JavaScript定时器管理工具</h1>
<p class="subtitle">创建、监控和清理setTimeout与setInterval定时器</p>
</header>
<div class="timer-controls">
<div class="control-group">
<label for="timerType">定时器类型</label>
<select id="timerType">
<option value="timeout">setTimeout (一次性)</option>
<option value="interval">setInterval (重复)</option>
</select>
</div>
<div class="control-group">
<label for="timerDuration">持续时间 (毫秒)</label>
<input type="number" id="timerDuration" min="100" max="100000" value="3000">
</div>
<div class="control-group">
<label for="timerMessage">定时器消息</label>
<input type="text" id="timerMessage" placeholder="输入定时器执行时显示的消息" value="定时器已触发!">
</div>
<div class="control-group">
<button id="addTimer" class="pulse">添加定时器</button>
</div>
</div>
<div class="actions">
<button id="clearAll" class="danger-btn">清理所有定时器</button>
</div>
<div class="timer-list" id="timerList">
<!-- 定时器列表将在这里动态生成 -->
<div class="empty-state">暂无活动定时器,请添加一个定时器开始使用</div>
</div>
<div class="stats">
<div class="stat-box">
<div class="stat-value" id="activeTimers">0</div>
<div class="stat-label">活动定时器</div>
</div>
<div class="stat-box">
<div class="stat-value" id="clearedTimers">0</div>
<div class="stat-label">已清理定时器</div>
</div>
<div class="stat-box">
<div class="stat-value" id="totalTimers">0</div>
<div class="stat-label">总定时器</div>
</div>
</div>
</div>
<script>
// 存储所有定时器的引用
const timers = [];
let timerIdCounter = 1;
// DOM元素
const timerList = document.getElementById('timerList');
const activeTimersEl = document.getElementById('activeTimers');
const clearedTimersEl = document.getElementById('clearedTimers');
const totalTimersEl = document.getElementById('totalTimers');
// 添加定时器
document.getElementById('addTimer').addEventListener('click', function() {
const type = document.getElementById('timerType').value;
const duration = parseInt(document.getElementById('timerDuration').value);
const message = document.getElementById('timerMessage').value;
if (isNaN(duration) || duration < 100) {
alert('请输入有效的持续时间(至少100毫秒)');
return;
}
const timerId = timerIdCounter++;
let timerRef;
// 创建定时器对象
const timerObj = {
id: timerId,
type: type,
duration: duration,
message: message,
status: 'active',
startTime: Date.now(),
progress: 0
};
// 根据类型设置定时器
if (type === 'timeout') {
timerRef = setTimeout(() => {
handleTimerCompletion(timerId);
alert(`定时器 #${timerId}: ${message}`);
}, duration);
timerObj.ref = timerRef;
} else {
timerRef = setInterval(() => {
alert(`定时器 #${timerId}: ${message}`);
}, duration);
timerObj.ref = timerRef;
}
timers.push(timerObj);
updateTimerList();
updateStats();
});
// 清理所有定时器
document.getElementById('clearAll').addEventListener('click', function() {
if (timers.length === 0) {
alert('没有活动定时器可清理');
return;
}
if (confirm(`确定要清理所有 ${timers.length} 个定时器吗?`)) {
timers.forEach(timer => {
if (timer.status === 'active') {
if (timer.type === 'timeout') {
clearTimeout(timer.ref);
} else {
clearInterval(timer.ref);
}
timer.status = 'cleared';
}
});
updateTimerList();
updateStats();
}
});
// 处理定时器完成
function handleTimerCompletion(timerId) {
const timer = timers.find(t => t.id === timerId);
if (timer) {
timer.status = 'completed';
updateTimerList();
updateStats();
}
}
// 清理单个定时器
function clearSingleTimer(timerId) {
const timer = timers.find(t => t.id === timerId);
if (timer && timer.status === 'active') {
if (timer.type === 'timeout') {
clearTimeout(timer.ref);
} else {
clearInterval(timer.ref);
}
timer.status = 'cleared';
updateTimerList();
updateStats();
}
}
// 更新定时器列表显示
function updateTimerList() {
const activeTimers = timers.filter(t => t.status === 'active');
if (activeTimers.length === 0) {
timerList.innerHTML = '<div class="empty-state">暂无活动定时器,请添加一个定时器开始使用</div>';
return;
}
let html = '';
activeTimers.forEach(timer => {
const elapsed = Date.now() - timer.startTime;
const progress = Math.min(100, (elapsed / timer.duration) * 100);
html += `
<div class="timer-item">
<div class="timer-info">
<div class="timer-id">定时器 #${timer.id}</div>
<div class="timer-details">
<span>类型: ${timer.type === 'timeout' ? 'setTimeout' : 'setInterval'}</span>
<span>持续时间: ${timer.duration}ms</span>
<span>消息: "${timer.message}"</span>
</div>
<div class="progress-bar">
<div class="progress" style="width: ${progress}%"></div>
</div>
</div>
<div class="timer-actions">
<span class="status status-active">活动</span>
<button class="danger-btn" onclick="clearSingleTimer(${timer.id})">清理</button>
</div>
</div>
`;
});
timerList.innerHTML = html;
// 更新进度条动画
setTimeout(updateProgressBars, 100);
}
// 更新进度条
function updateProgressBars() {
const activeTimers = timers.filter(t => t.status === 'active');
activeTimers.forEach(timer => {
const elapsed = Date.now() - timer.startTime;
const progress = Math.min(100, (elapsed / timer.duration) * 100);
// 如果是interval类型,进度条会循环
if (timer.type === 'interval' && progress >= 100) {
timer.startTime = Date.now();
}
});
if (activeTimers.length > 0) {
updateTimerList();
}
}
// 更新统计信息
function updateStats() {
const activeTimers = timers.filter(t => t.status === 'active').length;
const clearedTimers = timers.filter(t => t.status === 'cleared').length;
const totalTimers = timers.length;
activeTimersEl.textContent = activeTimers;
clearedTimersEl.textContent = clearedTimers;
totalTimersEl.textContent = totalTimers;
}
// 使clearSingleTimer函数在全局可用
window.clearSingleTimer = clearSingleTimer;
</script>
</body>
</html>