6KBhtm+js实现提交名单随机抽取功能适用活动或课堂随机点名

html 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>名单抽奖系统</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:Arial,sans-serif;min-height:100vh;background:#f5f5f5;display:flex;justify-content:center;align-items:center}
.container{width:90%;max-width:800px;text-align:center}
.input-section{background:white;padding:20px;border-radius:8px;box-shadow:0 2px 10px rgba(0,0,0,0.1);margin-bottom:20px}
#nameInput{width:100%;height:200px;padding:15px;border:1px solid #ddd;border-radius:4px;font-size:16px;resize:vertical;margin-bottom:15px}
.lottery-section{display:none;position:relative;height:400px;background:white;border-radius:8px;box-shadow:0 2px 10px rgba(0,0,0,0.1);overflow:hidden}
.name-display{position:absolute;padding:20px 40px;background:rgba(255,255,255,0.9);border-radius:8px;font-size:32px;font-weight:bold;color:#333;box-shadow:0 2px 15px rgba(0,0,0,0.1);transition:all 0.3s ease;opacity:0}
.btn{padding:12px 30px;font-size:16px;border:none;border-radius:4px;cursor:pointer;transition:all 0.3s ease;margin:10px}
.start-btn{background:#4CAF50;color:white}
.start-btn:hover{background:#45a049}
.stop-btn{background:#f44336;color:white}
.stop-btn:hover{background:#da190b}
.continue-btn{background:#2196F3;color:white}
.continue-btn:hover{background:#1976D2}
.final-result{font-size:48px;color:#333;text-shadow:2px 2px 4px rgba(0,0,0,0.1);animation:showResult 0.5s ease-out}
@keyframes showResult{from{transform:scale(0.5);opacity:0}
to{transform:scale(1);opacity:1}
}.drawn-names{margin-top:20px;padding:15px;background:rgba(255,255,255,0.9);border-radius:4px;font-size:14px;color:#666}
</style>
</head>
<body>
<div class="container">
<!-- 输入区域 -->
<div class="input-section" id="inputSection">
<textarea id="nameInput" placeholder="请输入名单,每行一个名字">
李一 李二 李三 李四 李五 李六 李七 李八 李九
</textarea>
<button class="btn start-btn" onclick="lottery.start()">开始抽奖</button>
</div>
<!-- 抽奖区域 -->
<div class="lottery-section" id="lotterySection">
<div class="name-display" id="nameDisplay"></div>
<button class="btn stop-btn" id="controlBtn">停止</button>
<div class="drawn-names" id="drawnNames"></div>
</div>
</div>
<script>
class LotterySystem {
constructor() {
this.nameList = [];         // 待抽取名单
this.drawnNames = [];       // 已抽取名单
this.isRunning = false;
this.animationInterval = null;
this.currentPosition = 0;
// 定义显示位置
this.positions = [
{ top: '10%', left: '50%', transform: 'translate(-50%, 0)' },
{ top: '50%', left: '10%', transform: 'translate(0, -50%)' },
{ top: '50%', left: '50%', transform: 'translate(-50%, -50%)' },
{ top: '50%', left: '90%', transform: 'translate(-100%, -50%)' },
{ top: '90%', left: '50%', transform: 'translate(-50%, -100%)' }
];
this.initElements();
}
initElements() {
this.inputSection = document.getElementById('inputSection');
this.lotterySection = document.getElementById('lotterySection');
this.nameInput = document.getElementById('nameInput');
this.nameDisplay = document.getElementById('nameDisplay');
this.controlBtn = document.getElementById('controlBtn');
this.drawnNamesDiv = document.getElementById('drawnNames');
this.controlBtn.addEventListener('click', () => this.toggleLottery());
}
processNames(input) {
// 提取有效字符(中文、英文、数字、@.-_)
const pattern = /[a-zA-Z0-9\u4e00-\u9fa5@._-]+/g;
const names = input.match(pattern) || [];
return [...new Set(names)]; // 去重
}
start() {
const input = this.nameInput.value.trim();
if (!input) {alert('请输入名单!');return;}
this.nameList = this.processNames(input);
if (this.nameList.length === 0) {alert('没有有效的名字!');return;}
this.inputSection.style.display = 'none';
this.lotterySection.style.display = 'block';
this.startAnimation();
}
startAnimation() {
this.isRunning = true;
this.controlBtn.textContent = '停止';
this.controlBtn.className = 'btn stop-btn';
let lastIndex = -1;
this.animationInterval = setInterval(() => {
if (!this.isRunning) return;
// 随机选择一个不同的索引
let newIndex;
do {
newIndex = Math.floor(Math.random() * this.nameList.length);
} while (newIndex === lastIndex && this.nameList.length > 1);
lastIndex = newIndex;
// 更新显示位置
this.currentPosition = (this.currentPosition + 1) % this.positions.length;
const position = this.positions[this.currentPosition];
// 更新显示
this.nameDisplay.style.opacity = 0;
setTimeout(() => {
Object.assign(this.nameDisplay.style, position);
this.nameDisplay.textContent = this.nameList[newIndex];
this.nameDisplay.style.opacity = 1;
}, 100);
}, 300);
}
stop() {
this.isRunning = false;
clearInterval(this.animationInterval);
// 随机选择最后一个名字
const finalIndex = Math.floor(Math.random() * this.nameList.length);
const drawnName = this.nameList[finalIndex];
// 从名单中移除已抽取的名字
this.nameList.splice(finalIndex, 1);
this.drawnNames.push(drawnName);
// 居中显示最终结果
Object.assign(this.nameDisplay.style, this.positions[2]);
this.nameDisplay.textContent = drawnName;
this.nameDisplay.classList.add('final-result');
// 更新已抽取名单显示
this.updateDrawnNames();
// 更新按钮状态
if (this.nameList.length > 0) {
this.controlBtn.textContent = '继续';
this.controlBtn.className = 'btn continue-btn';
} else {
this.controlBtn.textContent = '完成';
this.controlBtn.disabled = true;
}
}
updateDrawnNames() {
//不显示最终名单:过度间距名单和居中选中的显示会出现不一致情况
//this.drawnNamesDiv.textContent = `已抽取: ${this.drawnNames.join(',')}`;
}
toggleLottery() {
if (this.isRunning) {
this.stop();
} else {
this.nameDisplay.classList.remove('final-result');
this.startAnimation();
}
}
}
// 初始化抽奖系统
const lottery = new LotterySystem();
</script>
</body>
</html>
相关推荐
糕冷小美n6 小时前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥6 小时前
Technical Report 2024
java·服务器·前端
沐墨染6 小时前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion6 小时前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks6 小时前
前端将死,Agent 永生
前端·人工智能·ai编程
问道飞鱼7 小时前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建
爱上妖精的尾巴7 小时前
8-10 WPS JSA 正则表达式:贪婪匹配
服务器·前端·javascript·正则表达式·wps·jsa
shadow fish8 小时前
react学习记录(三)
javascript·学习·react.js
小疙瘩8 小时前
element-ui 中 el-upload 多文件一次性上传的实现
javascript·vue.js·ui
Aliex_git8 小时前
浏览器 API 兼容性解决方案
前端·笔记·学习