问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

智能随机点名系统

创作时间:
作者:
@小白创作中心

智能随机点名系统

引用
CSDN
1.
https://m.blog.csdn.net/weixin_47139678/article/details/145889919

在日常教学、会议签到、活动抽奖等场景中,随机点名系统是一个非常实用的工具。本文将介绍一个基于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文件

  1. 然后复制下面全部代码到这个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>
  1. 然后将dm.txt修改为dm.html

  2. 然后双击运行这个html文件

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

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号