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>
相关推荐
没资格抱怨14 分钟前
vue3中利用路由信息渲染菜单栏
前端·vue.js
TttHhhYy17 分钟前
vue写后台管理系统,有个需求将所有的$message消息提示换成确认框来增强消息提示效果,遇到嵌套过多的情况,出现某些问题
前端·javascript·vue.js·anti-design-vue
亿牛云爬虫专家35 分钟前
如何在Puppeteer中实现表单自动填写与提交:问卷调查
javascript·爬虫·爬虫代理·puppeteer·问卷调查·代理ip·表单
FIRE1 小时前
uniapp小程序分享使用canvas自定义绘制 vue3
前端·小程序·uni-app
四喜花露水1 小时前
vue elementui el-dropdown-item设置@click无效的解决方案
前端·vue.js·elementui
jokerest1231 小时前
web——sqliabs靶场——第五关——报错注入和布尔盲注
前端
焦糖酒1 小时前
终端应用开发沉思录
javascript·前端框架
谢尔登2 小时前
前端开发调试之 PC 端调试
开发语言·前端
每天吃饭的羊2 小时前
在循环中只set一次
开发语言·前端·javascript
_默_5 小时前
adminPage-vue3依赖DetailsModule版本说明:V1.2.1——1) - 新增span与labelSpan属性
前端·javascript·vue.js·npm·开源