数字闹钟源码网页版

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数字闹钟</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#E8F3FF',
                        accent: '#4080FF',
                        neutral: {
                            100: '#F5F7FA',
                            200: '#E4E7EB',
                            300: '#CBD2D9',
                            400: '#9AA5B1',
                            500: '#7B8794',
                            600: '#616E7C',
                            700: '#52606D',
                            800: '#3E4C59',
                            900: '#1F2933'
                        }
                    },
                    fontFamily: {
                        inter: ['Inter', 'sans-serif'],
                    },
                    boxShadow: {
                        'soft': '0 2px 12px rgba(22, 93, 255, 0.1)',
                        'hover': '0 4px 16px rgba(22, 93, 255, 0.2)',
                    }
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .bg-gradient-blue {
                background: linear-gradient(135deg, #E8F3FF 20%, #FFFFFF 80%);
            }
            .transition-all-300 {
                transition: all 0.3s ease;
            }
            .scale-hover {
                transition: transform 0.3s ease;
            }
            .scale-hover:hover {
                transform: translateY(-5px);
            }
            .time-input {
                @apply w-16 h-12 text-center text-xl font-medium border border-secondary rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/50;
            }
            .alarm-item {
                @apply flex items-center justify-between p-4 bg-white rounded-xl shadow-soft mb-3 transition-all-300 hover:shadow-hover;
            }
            .alarm-active {
                @apply border-l-4 border-primary;
            }
            .btn-primary {
                @apply bg-primary hover:bg-accent text-white px-6 py-3 rounded-lg font-medium transition-all-300 shadow-soft hover:shadow-hover flex items-center gap-2;
            }
            .btn-secondary {
                @apply bg-white hover:bg-secondary text-primary border border-secondary px-6 py-3 rounded-lg font-medium transition-all-300 shadow-soft hover:shadow-hover flex items-center gap-2;
            }
            .btn-danger {
                @apply bg-red-50 hover:bg-red-100 text-red-600 border border-red-200 px-4 py-2 rounded-lg font-medium transition-all-300;
            }
        }
    </style>
</head>
<body class="font-inter bg-gradient-blue min-h-screen flex flex-col">
    <!-- 导航栏 -->
    <nav class="w-full py-6 px-4 md:px-8">
        <div class="max-w-7xl mx-auto flex justify-between items-center">
            <div class="flex items-center space-x-2">
                <i class="fa fa-clock-o text-primary text-3xl"></i>
                <h1 class="text-2xl font-bold text-neutral-800">数字<span class="text-primary">闹钟</span></h1>
            </div>
            <div class="hidden md:flex space-x-8">
                <a href="#features" class="text-neutral-600 hover:text-primary transition-all-300 font-medium">功能</a>
                <a href="#settings" class="text-neutral-600 hover:text-primary transition-all-300 font-medium">设置</a>
                <a href="#about" class="text-neutral-600 hover:text-primary transition-all-300 font-medium">关于</a>
            </div>
            <button class="md:hidden text-neutral-800">
                <i class="fa fa-bars text-xl"></i>
            </button>
        </div>
    </nav>

    <!-- 主内容区 -->
    <main class="flex-grow w-full px-4 md:px-8 pb-16">
        <div class="max-w-7xl mx-auto">
            <!-- 当前时间显示 -->
            <section class="py-12 md:py-20 text-center">
                <h1 class="text-[clamp(2rem,5vw,3.5rem)] font-bold text-neutral-800 leading-tight">
                    现在时间: <span id="current-time" class="text-primary">00:00:00</span>
                </h1>
                <p class="text-lg text-neutral-600 mt-4">
                    设置闹钟,不错过任何重要时刻
                </p>
            </section>

            <!-- 闹钟设置区域 -->
            <section class="mt-16 md:mt-24 bg-white rounded-2xl shadow-soft p-8 md:p-12">
                <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
                    <!-- 左侧:添加闹钟表单 -->
                    <div class="bg-neutral-50 rounded-xl p-6 border border-neutral-200">
                        <h2 class="text-xl font-semibold text-neutral-800 mb-6 flex items-center">
                            <i class="fa fa-plus-circle text-primary mr-2"></i> 添加新闹钟
                        </h2>
                        
                        <form id="alarm-form" class="space-y-6">
                            <div class="flex items-center justify-center gap-4">
                                <input type="number" id="hour" min="0" max="23" value="09" class="time-input">
                                <span class="text-2xl text-neutral-400">:</span>
                                <input type="number" id="minute" min="0" max="59" value="00" class="time-input">
                                <span class="text-2xl text-neutral-400">:</span>
                                <input type="number" id="second" min="0" max="59" value="00" class="time-input">
                            </div>
                            
                            <div>
                                <label for="alarm-name" class="block text-neutral-700 font-medium mb-2">闹钟名称</label>
                                <input type="text" id="alarm-name" placeholder="例如:早上起床" class="w-full px-4 py-3 rounded-lg border border-secondary focus:outline-none focus:ring-2 focus:ring-primary/50">
                            </div>
                            
                            <div>
                                <label for="alarm-sound" class="block text-neutral-700 font-medium mb-2">闹钟铃声</label>
                                <select id="alarm-sound" class="w-full px-4 py-3 rounded-lg border border-secondary focus:outline-none focus:ring-2 focus:ring-primary/50">
                                    <option value="default">默认铃声</option>
                                    <option value="bird">鸟鸣声</option>
                                    <option value="waves">海浪声</option>
                                    <option value="rain">雨声</option>
                                    <option value="beep">蜂鸣声</option>
                                </select>
                            </div>
                            
                            <button type="submit" class="btn-primary justify-center w-full">
                                <i class="fa fa-clock-o"></i>
                                <span>设置闹钟</span>
                            </button>
                        </form>
                    </div>
                    
                    <!-- 右侧:闹钟列表 -->
                    <div>
                        <div class="flex justify-between items-center mb-6">
                            <h2 class="text-xl font-semibold text-neutral-800 flex items-center">
                                <i class="fa fa-list-ul text-primary mr-2"></i> 我的闹钟
                            </h2>
                            <span id="active-count" class="bg-primary/10 text-primary px-3 py-1 rounded-full text-sm font-medium">
                                0 个活跃
                            </span>
                        </div>
                        
                        <div id="alarm-list" class="space-y-3 max-h-[400px] overflow-y-auto pr-2">
                            <!-- 闹钟项目将通过JavaScript动态添加 -->
                            <div class="text-center text-neutral-500 py-10">
                                <i class="fa fa-clock-o text-4xl mb-4 text-neutral-300"></i>
                                <p>暂无闹钟,请添加新闹钟</p>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </main>

    <!-- 闹钟提醒弹窗 -->
    <div id="alarm-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
        <div class="bg-white rounded-2xl p-8 max-w-md w-full mx-4 transform transition-all duration-300 scale-100">
            <div class="text-center">
                <div class="text-5xl text-primary mb-4 animate-pulse">
                    <i class="fa fa-bell"></i>
                </div>
                <h3 class="text-2xl font-bold text-neutral-800 mb-2" id="ringing-name">闹钟时间到!</h3>
                <p class="text-neutral-600 mb-6" id="ringing-time">09:00:00</p>
                
                <div class="flex justify-center gap-4">
                    <button id="snooze-btn" class="btn-secondary">
                        <i class="fa fa-clock-o"></i>
                        <span>稍后提醒</span>
                    </button>
                    <button id="stop-btn" class="btn-primary">
                        <i class="fa fa-stop"></i>
                        <span>停止</span>
                    </button>
                </div>
            </div>
        </div>
    </div>

    <!-- 页脚 -->
    <footer class="bg-neutral-800 text-white py-12 px-4 md:px-8">
        <div class="max-w-7xl mx-auto">
            <div class="grid grid-cols-1 md:grid-cols-4 gap-8">
                <div>
                    <div class="flex items-center space-x-2 mb-6">
                        <i class="fa fa-clock-o text-primary text-2xl"></i>
                        <h2 class="text-xl font-bold">数字<span class="text-primary">闹钟</span></h2>
                    </div>
                    <p class="text-neutral-400 mb-6">简单而强大的网页闹钟,帮助您管理时间。</p>
                </div>
                
                <div>
                    <h3 class="text-lg font-semibold mb-6">功能</h3>
                    <ul class="space-y-3">
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">多闹钟管理</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">自定义铃声</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">稍后提醒</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">响应式设计</a></li>
                    </ul>
                </div>
                
                <div>
                    <h3 class="text-lg font-semibold mb-6">支持</h3>
                    <ul class="space-y-3">
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">帮助中心</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">常见问题</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">联系我们</a></li>
                    </ul>
                </div>
                
                <div>
                    <h3 class="text-lg font-semibold mb-6">法律</h3>
                    <ul class="space-y-3">
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">隐私政策</a></li>
                        <li><a href="#" class="text-neutral-400 hover:text-primary transition-all-300">服务条款</a></li>
                    </ul>
                </div>
            </div>
            
            <div class="mt-12 pt-8 border-t border-neutral-700 text-center text-neutral-400 text-sm">
                <p>© 2023 数字闹钟. 保留所有权利.</p>
            </div>
        </div>
    </footer>

    <script>
        // 音频资源
        const alarmSounds = {
            'default': 'https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3',
            'bird': 'https://assets.mixkit.co/sfx/preview/mixkit-birds-chirping-in-the-forest-529.mp3',
            'waves': 'https://assets.mixkit.co/sfx/preview/mixkit-waves-in-the-distance-1690.mp3',
            'rain': 'https://assets.mixkit.co/sfx/preview/mixkit-rain-falling-on-the-water-of-a-lake-1959.mp3',
            'beep': 'https://assets.mixkit.co/sfx/preview/mixkit-short-tone-alarm-990.mp3'
        };
        
        // 全局变量
        let alarms = [];
        let currentAudio = null;
        let alarmInterval = null;
        
        // DOM 元素
        const currentTimeEl = document.getElementById('current-time');
        const alarmListEl = document.getElementById('alarm-list');
        const activeCountEl = document.getElementById('active-count');
        const alarmForm = document.getElementById('alarm-form');
        const hourInput = document.getElementById('hour');
        const minuteInput = document.getElementById('minute');
        const secondInput = document.getElementById('second');
        const alarmNameInput = document.getElementById('alarm-name');
        const alarmSoundSelect = document.getElementById('alarm-sound');
        const alarmModal = document.getElementById('alarm-modal');
        const ringingNameEl = document.getElementById('ringing-name');
        const ringingTimeEl = document.getElementById('ringing-time');
        const snoozeBtn = document.getElementById('snooze-btn');
        const stopBtn = document.getElementById('stop-btn');
        
        // 初始化
        function init() {
            // 加载本地存储的闹钟
            loadAlarms();
            
            // 更新当前时间
            updateCurrentTime();
            setInterval(updateCurrentTime, 1000);
            
            // 更新闹钟状态
            startAlarmCheck();
            
            // 事件监听
            alarmForm.addEventListener('submit', addAlarm);
            snoozeBtn.addEventListener('click', snoozeAlarm);
            stopBtn.addEventListener('click', stopAlarm);
        }
        
        // 加载本地存储的闹钟
        function loadAlarms() {
            const savedAlarms = localStorage.getItem('alarms');
            if (savedAlarms) {
                alarms = JSON.parse(savedAlarms);
                renderAlarms();
            }
        }
        
        // 保存闹钟到本地存储
        function saveAlarms() {
            localStorage.setItem('alarms', JSON.stringify(alarms));
        }
        
        // 更新当前时间显示
        function updateCurrentTime() {
            const now = new Date();
            const hours = String(now.getHours()).padStart(2, '0');
            const minutes = String(now.getMinutes()).padStart(2, '0');
            const seconds = String(now.getSeconds()).padStart(2, '0');
            currentTimeEl.textContent = `${hours}:${minutes}:${seconds}`;
        }
        
        // 添加闹钟
        function addAlarm(e) {
            e.preventDefault();
            
            const hour = parseInt(hourInput.value);
            const minute = parseInt(minuteInput.value);
            const second = parseInt(secondInput.value);
            const name = alarmNameInput.value.trim() || `闹钟 ${alarms.length + 1}`;
            const sound = alarmSoundSelect.value;
            
            // 验证输入
            if (isNaN(hour) || hour < 0 || hour > 23) {
                showToast('小时必须在0-23之间');
                return;
            }
            
            if (isNaN(minute) || minute < 0 || minute > 59) {
                showToast('分钟必须在0-59之间');
                return;
            }
            
            if (isNaN(second) || second < 0 || second > 59) {
                showToast('秒钟必须在0-59之间');
                return;
            }
            
            // 创建闹钟对象
            const now = new Date();
            const alarmTime = new Date(
                now.getFullYear(),
                now.getMonth(),
                now.getDate(),
                hour,
                minute,
                second
            );
            
            // 如果设置的时间已经过去,则设置为明天
            if (alarmTime <= now) {
                alarmTime.setDate(alarmTime.getDate() + 1);
            }
            
            const alarm = {
                id: Date.now().toString(),
                time: alarmTime.toISOString(),
                name,
                sound,
                active: true
            };
            
            // 添加到闹钟列表
            alarms.push(alarm);
            saveAlarms();
            renderAlarms();
            
            // 重置表单
            alarmNameInput.value = '';
            
            // 显示成功提示
            showToast('闹钟已设置');
        }
        
        // 渲染闹钟列表
        function renderAlarms() {
            if (alarms.length === 0) {
                alarmListEl.innerHTML = `
                    <div class="text-center text-neutral-500 py-10">
                        <i class="fa fa-clock-o text-4xl mb-4 text-neutral-300"></i>
                        <p>暂无闹钟,请添加新闹钟</p>
                    </div>
                `;
                updateActiveCount();
                return;
            }
            
            // 按时间排序
            alarms.sort((a, b) => new Date(a.time) - new Date(b.time));
            
            alarmListEl.innerHTML = '';
            
            alarms.forEach(alarm => {
                const alarmTime = new Date(alarm.time);
                const hours = String(alarmTime.getHours()).padStart(2, '0');
                const minutes = String(alarmTime.getMinutes()).padStart(2, '0');
                const seconds = String(alarmTime.getSeconds()).padStart(2, '0');
                
                const alarmItem = document.createElement('div');
                alarmItem.className = `alarm-item ${alarm.active ? 'alarm-active' : ''}`;
                alarmItem.innerHTML = `
                    <div class="flex items-center gap-4">
                        <div class="w-12 h-12 bg-primary/10 rounded-lg flex items-center justify-center">
                            <i class="fa fa-clock-o text-primary text-xl"></i>
                        </div>
                        <div>
                            <h4 class="font-medium text-neutral-800">${alarm.name}</h4>
                            <p class="text-sm text-neutral-500">${hours}:${minutes}:${seconds}</p>
                        </div>
                    </div>
                    <div class="flex items-center gap-2">
                        <button class="toggle-alarm ${alarm.active ? 'text-primary' : 'text-neutral-400'}" data-id="${alarm.id}">
                            <i class="fa fa-toggle-${alarm.active ? 'on' : 'off'} text-xl"></i>
                        </button>
                        <button class="delete-alarm btn-danger" data-id="${alarm.id}">
                            <i class="fa fa-trash"></i>
                        </button>
                    </div>
                `;
                
                // 添加事件监听
                alarmItem.querySelector('.toggle-alarm').addEventListener('click', toggleAlarm);
                alarmItem.querySelector('.delete-alarm').addEventListener('click', deleteAlarm);
                
                alarmListEl.appendChild(alarmItem);
            });
            
            // 更新活跃闹钟计数
            updateActiveCount();
        }
        
        // 切换闹钟状态
        function toggleAlarm(e) {
            const id = e.currentTarget.getAttribute('data-id');
            const alarm = alarms.find(a => a.id === id);
            
            if (alarm) {
                alarm.active = !alarm.active;
                saveAlarms();
                renderAlarms();
                
                const message = alarm.active ? '闹钟已激活' : '闹钟已停用';
                showToast(message);
            }
        }
        
        // 删除闹钟
        function deleteAlarm(e) {
            const id = e.currentTarget.getAttribute('data-id');
            alarms = alarms.filter(a => a.id !== id);
            saveAlarms();
            renderAlarms();
            
            showToast('闹钟已删除');
        }
        
        // 更新活跃闹钟计数
        function updateActiveCount() {
            const activeCount = alarms.filter(a => a.active).length;
            activeCountEl.textContent = `${activeCount} 个活跃`;
        }
        
        // 开始检查闹钟
        function startAlarmCheck() {
            if (alarmInterval) {
                clearInterval(alarmInterval);
            }
            
            alarmInterval = setInterval(checkAlarms, 1000);
        }
        
        // 检查闹钟是否应该响铃
        function checkAlarms() {
            const now = new Date();
            
            alarms.forEach(alarm => {
                if (alarm.active) {
                    const alarmTime = new Date(alarm.time);
                    
                    // 如果当前时间等于闹钟时间,并且还没有处理过
                    if (
                        now.getHours() === alarmTime.getHours() &&
                        now.getMinutes() === alarmTime.getMinutes() &&
                        now.getSeconds() === alarmTime.getSeconds()
                    ) {
                        triggerAlarm(alarm);
                        
                        // 将闹钟设置为明天
                        const nextAlarmTime = new Date(alarmTime);
                        nextAlarmTime.setDate(nextAlarmTime.getDate() + 1);
                        alarm.time = nextAlarmTime.toISOString();
                        saveAlarms();
                    }
                }
            });
        }
        
        // 触发闹钟
        function triggerAlarm(alarm) {
            // 显示闹钟弹窗
            const alarmTime = new Date(alarm.time);
            const hours = String(alarmTime.getHours()).padStart(2, '0');
            const minutes = String(alarmTime.getMinutes()).padStart(2, '0');
            const seconds = String(alarmTime.getSeconds()).padStart(2, '0');
            
            ringingNameEl.textContent = alarm.name;
            ringingTimeEl.textContent = `${hours}:${minutes}:${seconds}`;
            
            // 播放闹钟声音
            if (currentAudio) {
                currentAudio.pause();
            }
            
            currentAudio = new Audio(alarmSounds[alarm.sound]);
            currentAudio.loop = true;
            currentAudio.play().catch(e => {
                console.error('播放声音失败:', e);
                showToast('播放声音失败,请确保浏览器允许播放声音');
            });
            
            // 显示弹窗
            alarmModal.classList.remove('hidden');
        }
        
        // 稍后提醒
        function snoozeAlarm() {
            // 停止当前闹钟声音
            if (currentAudio) {
                currentAudio.pause();
            }
            
            // 隐藏弹窗
            alarmModal.classList.add('hidden');
            
            // 添加一个5分钟后的新闹钟
            const now = new Date();
            now.setMinutes(now.getMinutes() + 5);
            
            const snoozeAlarm = {
                id: Date.now().toString(),
                time: now.toISOString(),
                name: '稍后提醒',
                sound: alarmSoundSelect.value,
                active: true
            };
            
            alarms.push(snoozeAlarm);
            saveAlarms();
            renderAlarms();
            
            showToast('已设置5分钟后提醒');
        }
        
        // 停止闹钟
        function stopAlarm() {
            // 停止当前闹钟声音
            if (currentAudio) {
                currentAudio.pause();
            }
            
            // 隐藏弹窗
            alarmModal.classList.add('hidden');
            
            showToast('闹钟已停止');
        }
        
        // 显示提示消息
        function showToast(message) {
            // 创建提示元素
            const toast = document.createElement('div');
            toast.className = 'fixed bottom-4 right-4 bg-neutral-800 text-white px-4 py-2 rounded-lg shadow-lg z-50 transform transition-all duration-300 translate-y-20 opacity-0';
            toast.textContent = message;
            
            // 添加到页面
            document.body.appendChild(toast);
            
            // 显示提示
            setTimeout(() => {
                toast.classList.remove('translate-y-20', 'opacity-0');
            }, 10);
            
            // 3秒后隐藏提示
            setTimeout(() => {
                toast.classList.add('translate-y-20', 'opacity-0');
                setTimeout(() => {
                    document.body.removeChild(toast);
                }, 300);
            }, 3000);
        }
        
        // 初始化应用
        init();
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄大新

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值