爆炸!用html为老师写个随机点名系统,点名直接用!!

在日常教学、会议签到、活动抽奖等场景中,随机点名系统是一个非常实用的工具。今天,我们就来一个基于 HTML、CSS 和 JavaScript 实现的智能随机点名系统的代码,并了解其功能和应用场景。

一、系统功能概述

这个智能随机点名系统主要具备以下功能:

  1. 添加姓名:用户可以通过输入框手动输入姓名并添加到点名列表中。

  2. 导入 Excel:支持从 Excel 文件(.csv 或.xlsx 格式)中批量导入姓名,方便快捷地录入大量数据。

  3. 随机点名:从已录入的姓名列表中随机抽取一个名字作为结果显示,同时提供了一个动画效果,增加趣味性。

  4. 删除姓名:可以单个删除指定的姓名,也支持批量删除已选中的姓名。

  5. 全选和取消全选:提供了全选和取消全选的功能,方便用户进行批量操作。

  6. 状态显示:实时显示当前点名列表中的人数,并且根据列表的状态动态更新操作按钮的可用性。

  7. 本地存储:系统使用本地存储(localStorage)来保存点名列表,确保数据在页面刷新或关闭后仍然存在。

    图片

二、代码结构分析

  1. HTML 结构:页面采用了简洁的布局,包含一个输入框、几个按钮、一个显示点名列表的无序列表、一个显示结果的区域以及一个状态显示条。通过不同的类名(如 .container.input-group.name-list 等)来组织和样式化各个元素。

  2. CSS 样式:使用了 CSS 变量(--primary-color--secondary-color--background)来定义主要的颜色,方便统一管理和修改。通过对不同类名的样式设置,实现了页面的美观和交互效果,如按钮的悬停效果、列表项的高亮效果等。

  3. JavaScript 逻辑

    • 初始化和数据存储:在页面加载时,从本地存储中读取已保存的姓名列表,并初始化页面显示。通过 saveToStorage 函数将更新后的列表保存到本地存储中。

    • 添加和删除姓名addName 函数负责将新的姓名添加到列表中,deleteName 函数用于删除指定的姓名。在添加或删除操作后,会更新列表显示、保存数据到本地存储,并根据列表状态更新按钮的可用性。

    • 批量操作toggleSelection 函数用于处理复选框的选中和取消选中状态,selectAll 函数实现全选和取消全选的功能,batchDelete 函数用于批量删除已选中的姓名。

    • Excel 导入handleFile 函数通过 FileReader 和 xlsx 库读取 Excel 文件内容,并将其中的姓名添加到点名列表中。在导入过程中,会显示一个加载提示,导入完成后更新列表和相关状态。

    • 随机点名randomPick 函数实现了随机点名的功能,通过一个动画效果在列表中快速切换姓名,最后随机抽取一个作为结果显示,并高亮显示选中的姓名。

三、应用场景

  1. 教学场景:教师可以使用该系统随机抽取学生回答问题,增加课堂互动性和公平性。

  2. 会议签到:在会议开始前,参会人员的姓名可以录入系统,会议过程中可以随机抽取参会人员进行发言或提问。

  3. 活动抽奖:在各种活动中,将参与者的姓名录入系统,通过随机点名来确定中奖者,增加活动的趣味性和公正性。

四、安装这个代码

  1. 新建一个.txt文件

    图片

  2. 然后复制下面全部代码到这个dm.txt中

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>智能随机点名系统</title>
        <style>
            :root {
                --primary-color: #2196F3;
                --secondary-color: #ff4081;
                --background: #f5f5f5;
            }
    
            body {
                font-family: 'Microsoft Yahei', Arial, sans-serif;
                background: var(--background);
                margin: 0;
                padding: 20px;
            }
    
            .container {
                max-width: 800px;
                margin: 0 auto;
                background: white;
                border-radius: 12px;
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
                padding: 30px;
            }
    
            .header {
                text-align: center;
                margin-bottom: 30px;
            }
    
            .input-group {
                display: flex;
                gap: 10px;
                margin-bottom: 20px;
            }
    
            input[type="text"] {
                flex: 1;
                padding: 12px;
                border: 2px solid #ddd;
                border-radius: 6px;
                transition: border-color 0.3s;
            }
    
            input[type="text"]:focus {
                border-color: var(--primary-color);
                outline: none;
            }
    
            button {
                padding: 12px 24px;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                transition: all 0.3s;
                background: var(--primary-color);
                color: white;
            }
    
            button:hover {
                opacity: 0.9;
                transform: translateY(-1px);
            }
    
            button:disabled {
                background: #ccc;
                cursor: not-allowed;
            }
    
            .file-input {
                position: relative;
                display: inline-block;
            }
    
            .file-input input[type="file"] {
                position: absolute;
                left: 0;
                top: 0;
                opacity: 0;
                width: 100%;
                height: 100%;
                cursor: pointer;
            }
    
            .name-list {
                list-style: none;
                padding: 0;
                margin: 20px 0;
                border: 2px solid #eee;
                border-radius: 8px;
                max-height: 300px;
                overflow-y: auto;
            }
    
            .name-list li {
                padding: 15px;
                margin: 0;
                border-bottom: 1px solid #eee;
                display: flex;
                justify-content: space-between;
                align-items: center;
                transition: all 0.3s;
            }
    
            .name-list li:last-child {
                border-bottom: none;
            }
    
            .name-list li:hover {
                background: #f8f9fa;
            }
    
            .name-list .name-content {
                flex: 1;
                margin-left: 10px;
            }
    
            .highlight {
                background: #fff3e0 !important;
                font-weight: bold;
            }
    
            .result-box {
                text-align: center;
                padding: 30px;
                margin: 20px 0;
                background: #f8f9fa;
                border-radius: 8px;
                min-height: 100px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 24px;
                color: var(--primary-color);
                transition: all 0.3s;
            }
    
            @keyframes spin {
                0% { transform: scale(1); opacity: 1; }
                50% { transform: scale(1.2); opacity: 0.8; }
                100% { transform: scale(1); opacity: 1; }
            }
    
            .spinning {
                animation: spin 0.1s infinite;
                color: var(--secondary-color);
            }
    
            .status-bar {
                text-align: right;
                color: #666;
                font-size: 14px;
                margin-top: 20px;
            }
    
            .delete-btn {
                background: var(--secondary-color);
                padding: 6px 12px;
                font-size: 12px;
            }
    
            .loading {
                display: none;
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(255, 255, 255, 0.8);
                justify-content: center;
                align-items: center;
                z-index: 1000;
            }
    
            .loading.active {
                display: flex;
            }
    
            .batch-actions {
                display: flex;
                gap: 10px;
                margin-bottom: 10px;
            }
    
            .delete-all-btn {
                background: var(--secondary-color);
            }
    
            .name-checkbox {
                margin-right: 10px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>🎉 智能随机点名系统</h1>
            </div>
    
            <div class="input-group">
                <input type="text" id="nameInput" placeholder="请输入姓名...">
                <button onclick="addName()">➕ 添加</button>
                <div class="file-input">
                    <button>📁 导入Excel</button>
                    <input type="file" id="excelFile" accept=".csv,.xlsx" onchange="handleFile()">
                </div>
                <button onclick="randomPick()" id="pickBtn" disabled>🎮 开始点名</button>
            </div>
    
            <div class="batch-actions">
                <button onclick="selectAll()" id="selectAllBtn">全选</button>
                <button onclick="batchDelete()" class="delete-all-btn" id="batchDeleteBtn" disabled>批量删除</button>
            </div>
    
            <ul class="name-list" id="nameList"></ul>
    
            <div class="result-box" id="result">
                👇 点击上方按钮开始
            </div>
    
            <div class="status-bar">
                当前人数: <span id="count">0</span>
            </div>
        </div>
    
        <div class="loading" id="loading">
            <div style="font-size: 24px; color: var(--primary-color)">⏳ 正在导入数据...</div>
        </div>
    
        <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.5/xlsx.full.min.js"></script>
        <script>
            // 初始化本地存储
            let names = JSON.parse(localStorage.getItem('names')) || [];
            let isSpinning = false;
            let selectedNames = [];
    
            // 页面加载时初始化列表
            window.onload = () => {
                renderList();
                updateButtonState();
                updateCount();
            };
    
            function saveToStorage() {
                localStorage.setItem('names', JSON.stringify(names));
                updateCount();
            }
    
            function updateCount() {
                document.getElementById('count').textContent = names.length;
            }
    
            function updateButtonState() {
                const pickBtn = document.getElementById('pickBtn');
                pickBtn.disabled = names.length < 2;
                
                const batchDeleteBtn = document.getElementById('batchDeleteBtn');
                batchDeleteBtn.disabled = selectedNames.length === 0;
            }
    
            function renderList() {
                const list = document.getElementById('nameList');
                list.innerHTML = names.map(name => `
                    <li>
                        <input type="checkbox" class="name-checkbox" onchange="toggleSelection('${name}', this.checked)">
                        <span class="name-content">${name}</span>
                        <button class="delete-btn" onclick="deleteName('${name}')">删除</button>
                    </li>
                `).join('');
                selectedNames = [];
                updateButtonState();
            }
    
            function addName(name) {
                const nameToAdd = name || document.getElementById('nameInput').value.trim();
                if (nameToAdd && !names.includes(nameToAdd)) {
                    names.push(nameToAdd);
                    renderList();
                    document.getElementById('nameInput').value = '';
                    saveToStorage();
                    updateButtonState();
                }
            }
    
            function deleteName(name) {
                names = names.filter(n => n !== name);
                selectedNames = selectedNames.filter(n => n !== name);
                renderList();
                saveToStorage();
                updateButtonState();
            }
    
            function toggleSelection(name, isChecked) {
                if (isChecked) {
                    if (!selectedNames.includes(name)) {
                        selectedNames.push(name);
                    }
                } else {
                    selectedNames = selectedNames.filter(n => n !== name);
                }
                updateButtonState();
            }
    
            function selectAll() {
                const checkboxes = document.querySelectorAll('.name-checkbox');
                const selectAllBtn = document.getElementById('selectAllBtn');
                
                // 检查是否所有都已选中
                const allSelected = selectedNames.length === names.length;
                
                if (allSelected) {
                    // 如果全部已选中,则取消全选
                    checkboxes.forEach(cb => cb.checked = false);
                    selectedNames = [];
                    selectAllBtn.textContent = '全选';
                } else {
                    // 否则全选
                    checkboxes.forEach(cb => cb.checked = true);
                    selectedNames = [...names];
                    selectAllBtn.textContent = '取消全选';
                }
                
                updateButtonState();
            }
    
            function batchDelete() {
                if (selectedNames.length === 0) return;
                
                if (confirm(`确定要删除选中的 ${selectedNames.length} 个名字吗?`)) {
                    names = names.filter(name => !selectedNames.includes(name));
                    selectedNames = [];
                    renderList();
                    saveToStorage();
                    updateButtonState();
                }
            }
    
            async function handleFile() {
                const file = document.getElementById('excelFile').files[0];
                if (!file) return;
    
                document.getElementById('loading').classList.add('active');
                
                const reader = new FileReader();
                reader.onload = async function(e) {
                    const data = new Uint8Array(e.target.result);
                    const workbook = XLSX.read(data, {type: 'array'});
                    const sheet = workbook.Sheets[workbook.SheetNames[0]];
                    const json = XLSX.utils.sheet_to_json(sheet);
                    
                    json.forEach(row => {
                        const name = Object.values(row)[0]?.toString().trim();
                        if (name && !names.includes(name)) {
                            names.push(name);
                        }
                    });
    
                    renderList();
                    saveToStorage();
                    updateButtonState();
                    document.getElementById('loading').classList.remove('active');
                };
                reader.readAsArrayBuffer(file);
            }
    
            function randomPick() {
                if (isSpinning || names.length < 2) return;
                
                isSpinning = true;
                const resultDiv = document.getElementById('result');
                const btn = document.getElementById('pickBtn');
                btn.disabled = true;
                
                let currentIndex = 0;
                let interval = 50;
                let rounds = 15;
                resultDiv.classList.add('spinning');
    
                const animate = () => {
                    resultDiv.textContent = names[currentIndex];
                    currentIndex = (currentIndex + 1) % names.length;
                    
                    if (rounds-- > 0) {
                        interval += 10;
                        setTimeout(animate, interval);
                    } else {
                        const winner = names[Math.floor(Math.random() * names.length)];
                        resultDiv.textContent = `🎉 中奖者: ${winner}`;
                        resultDiv.classList.remove('spinning');
                        btn.disabled = false;
                        isSpinning = false;
                        
                        document.querySelectorAll('#nameList li').forEach(li => {
                            li.classList.toggle('highlight', li.querySelector('.name-content').textContent.includes(winner));
                        });
                    }
                };
    
                setTimeout(animate, interval);
            }
        </script>
    </body>
    </html>
    

  3. 然后将dm.txt修改为dm.html:
     

图片

4。然后双击运行这个html文件

图片

5、就可以看到这个点名系统了

创作不易,从构思到成品,饱含我创作的热忱,希望大家尊重原创,拒绝抄袭、盗用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值