普通视图

发现新文章,点击刷新页面。
今天 — 2026年1月31日首页

纯原生html js实现幸运抽奖转盘功能-奖项不重复(javascript小案例)

作者 崧峻
2026年1月31日 09:21

创建项目

如图所示创建一个基本html项目,创建好之后如图2所示 image.png

九宫格效果

我们先来实现九宫格的效果吧,有两种一种是按照顺序的九宫格如图1所示,一种是一圈的效果如图2所示,我们本期以第一种九宫格为案例进行实现

image.pngimage.png

html部分代码

<body>
<div id="turntable-box">
<div>一等奖</div>
<div>二等奖</div>
<div>三等奖</div>
<div>四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div>五等奖</div>
<div>六等奖</div>
<div>七等奖</div>
<div>八等奖</div>
</div>
</body>

css部分代码样式

<style type="text/css">

  


/* 转盘的外层边框 */

#turntable-box {

display: flex;

align-items: center;

justify-content: center;

flex-wrap: wrap;

gap: 15px;

border-radius: 15px;

background-color: #922a21;

position: relative;

width: 510px;

height: 420px;

margin: 0 auto;

padding: 20px;

}

  


/* 转盘下面的每个模块样式 */

#turntable-box > div {

display: flex;

align-items: center;

justify-content: center;

border-radius: 25px;

width: 160px;

background-color: #f8e7c1;

height: 130px;

text-align: center;

font-size: 25px;

}

</style>

这个就是很简单的一个换行排序 flex布局

#turntable-box .reward:nth-child(1) {
top: 10px;
left: 10px;
}

#turntable-box .reward:nth-child(2) {
top: 10px;
left: 175px;
}
#turntable-box .reward:nth-child(3) {
top: 10px;
left: 340px;
}
#turntable-box .reward:nth-child(4) {
left: 340px;
top: 145px;
}
#turntable-box .reward:nth-child(5) {
left: 340px;
top: 280px;
}
#turntable-box .reward:nth-child(6) {
top: 280px;
left: 175px;
}
#turntable-box .reward:nth-child(7) {
left: 10px;
top: 280px;
}
#turntable-box .reward:nth-child(8) {
left: 10px;
top: 145px;
}

如果大家想要一圈形式的布局代码参考如下 其实就是利用了定位让他形成了一圈

美化样式

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>幸运转盘</title>
<style type="text/css">
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100vw;
height: 100vh;
background: url('img/background.jpg');
/* 背景图片居中 */
background-position: center;
/* 背景图片不重复 */
background-repeat: no-repeat;
}


/* 幸运抽奖的标题图片 */
.draw-title {
z-index: 10;
width: 300px;
transform: translateY(10px);
}


/*  转盘的外层边框 */
#turntable-content {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 5px;
border-radius: 15px;
background-color: #922a21;
position: relative;
width: 510px;
height: 410px;
margin: 0 auto;
padding: 10px;
}


/*  转盘下面的每个模块样式 */
#turntable-content>div {
display: flex;
align-items: center;
justify-content: center;
border-radius: 25px;
width: 160px;
height: 130px;
text-align: center;
font-size: 25px;
}






/* 幸运转盘最外层 */
.draw-turntable-box {
display: flex;
align-items: center;
justify-content: center;
border-radius: 5%;
background: #de4b3f;
height: 500px;
width: 600px;
}


/* 开始抽奖按钮 */
#startBtn {
cursor: pointer;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
white-space: normal;
background-color: #eb5e4a;
color: white;
}

/* 奖项 */
.unselected {
background-color: #f8e7c1;
}

#selected {
background-color: #ee7c45;
}
</style>
</head>
<body>
<img src="./img/draw.jpg" alt="抽奖标题" class="draw-title" />
<div class="draw-turntable-box">
<div id="turntable-content">
<div class="award unselected">一等奖</div>
<div class="award unselected">二等奖</div>
<div class="award unselected">三等奖</div>
<div class="award unselected">四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div class="award unselected">五等奖</div>
<div class="award unselected">六等奖</div>
<div class="award unselected">七等奖</div>
<div class="award unselected">八等奖</div>
</div>
</div>
</body>
</html>

js代码实现-抽奖不重复

image.png 实现原理是给开始按钮绑定一个点击事件,然后进行依次变色,最后随机一个没有抽到过的数,然后抽奖成功后把这个数放到一个变量中存储进行去重,完整js代码如下 如图所示

// 奖项元素列表
var award = document.getElementsByClassName("award");
// 已经拿到的奖励序号
const lucks = [];
// 是否正在抽奖
let running = false;

// 开始按钮元素
var startBtn = document.getElementById("startBtn");

startBtn.onclick = function() {
// 判断是否正在抽奖
if (running) return;
// 设置为正在抽奖
running = true;

// 可抽取的奖项编号(1~8)排除已经抽取的
const available = Array.from({ length: award.length }, (_, i) => i + 1)
.filter(i => !lucks.includes(i));

// 全部抽完
if (available.length === 0) {
startBtn.innerHTML = "所有奖项已抽完";
running = false;
return;
}

// 随机中奖编号(1~8中未抽的一个)
const target = available[Math.floor(Math.random() * available.length)];

// 随机圈数(2~4圈)
const rounds = Math.floor(Math.random() * 2) + 2;
const totalSteps = rounds * award.length + (target - 1);

let current = 0;
let speed = 60;

function spin() {
const index = current % award.length;

// 重置未中奖项颜色
for (let i = 0; i < award.length; i++) {
if (!lucks.includes(i + 1)) {
award[i].className = "award unselected";
}
}

// 高亮当前
award[index].className = "selected award";

current++;

// 是否结束
if (current > totalSteps) {
lucks.push(index + 1);
startBtn.innerHTML = `恭喜您中了<br>${index + 1}等奖 🎊`;
running = false;
return;
}

// 越接近目标速度越慢
if (totalSteps - current < award.length) {
speed += 40;
}

setTimeout(spin, speed);
}

spin();
};
</script>

完整代码



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>幸运转盘</title>
<style type="text/css">
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100vw;
height: 100vh;
background: url('img/background.jpg');
/* 背景图片居中 */
background-position: center;
/* 背景图片不重复 */
background-repeat: no-repeat;
}


/* 幸运抽奖的标题图片 */
.draw-title {
z-index: 10;
width: 300px;
transform: translateY(10px);
}


/*  转盘的外层边框 */
#turntable-content {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 5px;
border-radius: 15px;
background-color: #922a21;
position: relative;
width: 510px;
height: 410px;
margin: 0 auto;
padding: 10px;
}


/*  转盘下面的每个模块样式 */
#turntable-content>div {
display: flex;
align-items: center;
justify-content: center;
border-radius: 25px;
width: 160px;
height: 130px;
text-align: center;
font-size: 25px;
}






/* 幸运转盘最外层 */
.draw-turntable-box {
display: flex;
align-items: center;
justify-content: center;
border-radius: 5%;
background: #de4b3f;
height: 500px;
width: 600px;
}


/* 开始抽奖按钮 */
#startBtn {
cursor: pointer;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
white-space: normal;
background-color: #eb5e4a;
color: white;
}

/* 奖项 */
.unselected {
background-color: #f8e7c1;
}

.selected {
background-color: #ee7c45;
}
</style>
</head>
<body>
<img src="./img/draw.jpg" alt="抽奖标题" class="draw-title" />
<div class="draw-turntable-box">
<div id="turntable-content">
<div class="award unselected">一等奖</div>
<div class="award unselected">二等奖</div>
<div class="award unselected">三等奖</div>
<div class="award unselected">四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div class="award unselected">五等奖</div>
<div class="award unselected">六等奖</div>
<div class="award unselected">七等奖</div>
<div class="award unselected">八等奖</div>
</div>
</div>
</body>


<script type="text/javascript">
// 奖项元素列表
var award = document.getElementsByClassName("award");
// 已经拿到的奖励序号
const lucks = [];
// 是否正在抽奖
let running = false;

// 开始按钮元素
var startBtn = document.getElementById("startBtn");

startBtn.onclick = function() {
// 判断是否正在抽奖
if (running) return;
// 设置为正在抽奖
running = true;

// 可抽取的奖项编号(1~8)排除已经抽取的
const available = Array.from({ length: award.length }, (_, i) => i + 1)
.filter(i => !lucks.includes(i));

// 全部抽完
if (available.length === 0) {
startBtn.innerHTML = "所有奖项已抽完";
running = false;
return;
}

// 随机中奖编号(1~8中未抽的一个)
const target = available[Math.floor(Math.random() * available.length)];

// 随机圈数(2~4圈)
const rounds = Math.floor(Math.random() * 2) + 2;
const totalSteps = rounds * award.length + (target - 1);

let current = 0;
let speed = 60;

function spin() {
const index = current % award.length;

// 重置未中奖项颜色
for (let i = 0; i < award.length; i++) {
if (!lucks.includes(i + 1)) {
award[i].className = "award unselected";
}
}

// 高亮当前
award[index].className = "selected award";

current++;

// 是否结束
if (current > totalSteps) {
lucks.push(index + 1);
startBtn.innerHTML = `恭喜您中了<br>${index + 1}等奖 🎊`;
running = false;
return;
}

// 越接近目标速度越慢
if (totalSteps - current < award.length) {
speed += 40;
}

setTimeout(spin, speed);
}

spin();
};
</script>
</html>

转载自DOIT社区纯原生html js实现幸运抽奖转盘功能-奖项不重复(javascript小案例)-DOIT社区 如有需要大家可以去此地址拿取文件

❌
❌