智能喝水提醒
规律饮水,健康生活,告别忘记喝水的烦恼
记录饮水
ml
该喝水啦!
保持规律饮水,让身体更健康
确认清空今日记录?
此操作将删除今日所有饮水记录,且无法恢复
智能喝水提醒工具
`;
recordsList.appendChild(recordEl);
});
// 添加删除事件监听
document.querySelectorAll('.delete-record').forEach(btn => {
btn.addEventListener('click', function() {
const index = parseInt(this.dataset.index);
deleteRecord(index);
});
});
}
// 添加饮水记录
function addWaterRecord(amount) {
if (amount <= 0) return;
// 获取当前时间
const now = new Date();
const timeStr = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
// 添加记录
waterRecords.push({
amount,
time: timeStr,
timestamp: now.getTime()
});
// 更新总饮水量
totalConsumed += amount;
// 更新界面
updateUI();
// 显示提示
showToast(`已记录 ${amount} ml 饮水量`);
}
// 删除记录
function deleteRecord(index) {
if (index >= 0 && index < waterRecords.length) {
const amount = waterRecords[index].amount;
waterRecords.splice(index, 1);
totalConsumed -= amount;
updateUI();
showToast('记录已删除');
}
}
// 清空今日记录
function clearAllRecords() {
if (waterRecords.length === 0) {
showToast('没有可清空的记录', 'error');
return;
}
totalConsumed = 0;
waterRecords = [];
updateUI();
hideClearConfirm();
showToast('今日记录已清空');
}
// 启动提醒
function startReminder() {
// 清除现有定时器
if (reminderTimer) {
clearInterval(reminderTimer);
}
// 获取输入值并验证
const goal = parseInt(dailyGoalInput.value, 10);
const interval = parseFloat(reminderIntervalInput.value);
if (isNaN(goal) || goal < 500 || goal > 5000) {
showToast('请设置有效的每日喝水目标(500-5000ml)', 'error');
return;
}
if (isNaN(interval) || interval < 0.5 || interval > 8) {
showToast('请设置有效的提醒间隔(0.5-8小时)', 'error');
return;
}
// 更新设置
dailyGoal = goal;
reminderInterval = interval;
// 转换间隔为毫秒
const intervalMs = interval * 60 * 60 * 1000;
// 设置新定时器
reminderTimer = setInterval(showReminder, intervalMs);
// 保存数据并更新界面
saveData();
updateUI();
// 显示提示
showToast(`提醒已设置,将每 ${interval} 小时提醒一次`);
}
// 显示喝水提醒
function showReminder() {
// 显示提醒弹窗
reminderModal.classList.remove('hidden');
setTimeout(() => {
modalContent.classList.remove('scale-95', 'opacity-0');
modalContent.classList.add('scale-100', 'opacity-100');
}, 50);
// 播放提示音(简化版,避免Base64问题)
try {
const audio = new Audio('data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAA==');
audio.play().catch(e => console.log('提示音播放失败:', e));
} catch (e) {
console.log('提示音初始化失败:', e);
}
}
// 隐藏提醒弹窗
function hideReminder() {
modalContent.classList.remove('scale-100', 'opacity-100');
modalContent.classList.add('scale-95', 'opacity-0');
setTimeout(() => {
reminderModal.classList.add('hidden');
}, 300);
}
// 显示清空确认对话框
function showClearConfirm() {
confirmDialog.classList.remove('hidden');
setTimeout(() => {
dialogContent.classList.remove('scale-95', 'opacity-0');
dialogContent.classList.add('scale-100', 'opacity-100');
}, 50);
}
// 隐藏清空确认对话框
function hideClearConfirm() {
dialogContent.classList.remove('scale-100', 'opacity-100');
dialogContent.classList.add('scale-95', 'opacity-0');
setTimeout(() => {
confirmDialog.classList.add('hidden');
}, 300);
}
// 显示提示消息
function showToast(message, type = 'success') {
toastMessage.textContent = message;
if (type === 'success') {
toast.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 translate-y-0 opacity-100 transition-all duration-300 flex items-center px-4 py-2.5 rounded-lg shadow-lg z-50 max-w-xs bg-green-500 text-white';
toast.querySelector('i').className = 'fa fa-check-circle mr-2';
} else {
toast.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 translate-y-0 opacity-100 transition-all duration-300 flex items-center px-4 py-2.5 rounded-lg shadow-lg z-50 max-w-xs bg-red-500 text-white';
toast.querySelector('i').className = 'fa fa-exclamation-circle mr-2';
}
setTimeout(() => {
toast.className = 'fixed bottom-6 left-1/2 transform -translate-x-1/2 translate-y-20 opacity-0 transition-all duration-300 flex items-center px-4 py-2.5 rounded-lg shadow-lg z-50 max-w-xs';
}, 3000);
}
// 设置事件监听器
function setupEventListeners() {
// 保存设置按钮
saveSettingsBtn.addEventListener('click', startReminder);
// 快捷添加按钮
addWaterBtns.forEach(btn => {
btn.addEventListener('click', function() {
const amount = parseInt(this.dataset.amount);
addWaterRecord(amount);
});
});
// 自定义添加按钮
addCustomBtn.addEventListener('click', function() {
const amount = parseInt(customAmountInput.value);
if (isNaN(amount) || amount < 50) {
showToast('请输入有效的饮水量(至少50ml)', 'error');
customAmountInput.focus();
return;
}
addWaterRecord(amount);
customAmountInput.value = ''; // 清空输入框
});
// 清空记录按钮
clearRecordsBtn.addEventListener('click', showClearConfirm);
// 取消清空按钮
cancelClearBtn.addEventListener('click', hideClearConfirm);
// 确认清空按钮
confirmClearBtn.addEventListener('click', clearAllRecords);
// 已喝水按钮
drankBtn.addEventListener('click', function() {
hideReminder();
// 默认添加200ml
addWaterRecord(200);
});
// 稍后提醒按钮
snoozeBtn.addEventListener('click', function() {
hideReminder();
// 10分钟后再次提醒
setTimeout(showReminder, 10 * 60 * 1000);
showToast('将在10分钟后再次提醒');
});
// 点击对话框外部关闭
confirmDialog.addEventListener('click', function(e) {
if (e.target === confirmDialog) {
hideClearConfirm();
}
});
// 点击提醒框外部关闭
reminderModal.addEventListener('click', function(e) {
if (e.target === reminderModal) {
hideReminder();
}
});
// 自定义输入框回车提交
customAmountInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
addCustomBtn.click();
}
});
}
// 页面加载完成后初始化
// 导出今日记录为JSON
var exportBtn = document.getElementById('exportBtn');
if (exportBtn) {
exportBtn.addEventListener('click', function() {
var exportData = {
date: today,
goal: dailyGoal,
totalConsumed: totalConsumed,
unit: 'ml',
achieved: totalConsumed >= dailyGoal,
progressPercent: Math.round((totalConsumed / dailyGoal) * 100),
records: waterRecords
};
var blob = new Blob([JSON.stringify(exportData, null, 2)], {type: 'application/json'});
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'water-record-' + today + '.json';
a.click();
URL.revokeObjectURL(url);
showToast('今日记录已导出!');
});
}
// 打印饮水报告
var printBtn = document.getElementById('printBtn');
if (printBtn) {
printBtn.addEventListener('click', function() {
window.print();
});
}
// 返回顶部按钮
(function() {
var btn = document.getElementById('backToTop');
if (btn) {
window.addEventListener('scroll', function() {
btn.style.display = window.scrollY > 300 ? 'flex' : 'none';
});
btn.addEventListener('click', function() {
window.scrollTo({top: 0, behavior: 'smooth'});
});
}
})();
document.addEventListener('DOMContentLoaded', init);