用 HTML、CSS 和 JavaScript 实现抽奖转盘效果

顺序抽奖

前言

这段代码实现了一个简单的抽奖转盘效果。页面上有一个九宫格布局的抽奖区域,周围八个格子分别放置了不同的奖品名称,中间是一个 "开始抽奖" 的按钮。点击按钮后,抽奖区域的格子会快速滚动,颜色不断变化,模拟抽奖过程。经过一定圈数的滚动后,会随机停止在某一个格子上,弹出提示框显示中奖奖品。

效果展示

代码详情

HTML部分

html 复制代码
<div class="box">
    <div class="div1">电脑</div>
    <div class="div2">手机</div>
    <div class="div3">音响</div>
    <div class="div4">冰箱</div>
    <div class="div5">空调</div>
    <div class="div6">衣柜</div>
    <div class="div7">沙发</div>
    <div class="div8">地毯</div>
    <button class="giftButton">开始抽奖</button>
</div>

CSS部分

javascript 复制代码
* {
    margin: 0;
    padding: 0;
}

.box {
    background-color: lightgray;
    width: 340px;
    height: 340px;
    position: relative;
}

.box div {
    background-color: cadetblue;
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
}

.div1 {
    position: absolute;
    top: 10px;
    left: 10px;
}

/* 其他 .divX 类的样式省略,它们类似地设置了不同的 top 和 left 值来定位 */

.giftButton {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 120px;
    left: 120px;
    border-radius: 10px;
    background-color: navajowhite;
}

JS部分

初始化声明
  • boxCenter:通过 document.getElementsByClassName('box')[0] 获取到类名为 box 的元素,这个元素是整个抽奖区域的容器。
  • allGift:使用 boxCenter.getElementsByTagName('div') 获取 boxCenter 内的所有 div 元素,这些 div 元素代表了各个奖品格子。
  • giftButtons:通过 document.getElementsByClassName('giftButton')[0] 获取 "开始抽奖" 按钮元素,后续会为它添加点击事件。
  • k:作为奖品的下标,用于标记当前高亮显示的奖品格子。
  • time:旋转时间间隔,初始值为 500 毫秒,后续会根据抽奖过程动态调整。
  • count:记录抽奖过程中转过的圈数,初始值为 0。
  • inter:用于存储定时器,方便后续清除和重新设置定时器。
  • random:存储随机生成的中奖下标,初始值为 0。
javascript 复制代码
//获取box
let boxCenter = document.getElementsByClassName('box')[0];
//获取boxcenter里的所有的div元素
let allGift = boxCenter.getElementsByTagName('div');
//获取到抽奖按钮,后续帮点击事件
let giftButtons = document.getElementsByClassName('giftButton')[0];
//充当奖品的下标
let k = 0;
// 旋转时间间隔
let time = 500;
//圈数,就是转动的圈数
let count = 0;
//存定时器的
let inter;
//随机的数(中奖的下标)
let random = 0;
点击按钮事件
  • giftButtons 按钮添加 onclick 事件处理函数。
  • 当点击按钮时,将当前 k 对应的奖品格子背景颜色设置为黄色,表示高亮显示。
  • 使用 Math.random() 生成一个 0 到 1 之间的随机数,乘以 allGift.length 得到一个随机范围在 0 到奖品数量之间的数,再使用 Math.floor() 向下取整,得到一个随机的中奖下标 random
  • 使用 setInterval() 函数设置一个定时器,每隔 time 毫秒执行一次 autoScroll 函数,开始抽奖滚动过程。
javascript 复制代码
//上点击事件
giftButtons.onclick = function() {
    //奖品的下标k变颜色 
    allGift[k].style.backgroundColor = 'yellow';
    // 先生成一个随机数,然后*box里的所有div的数量,再向下取整
    random = Math.floor(Math.random() * allGift.length);
    //设定时器
    inter = setInterval(autoScroll, time);
}
滚动函数
  1. 奖品格子切换
    • 如果 k 小于 allGift.length - 1,说明还没有转到最后一个奖品格子,将 k 加 1,把上一个奖品格子的背景颜色变回 cadetblue,当前 k 对应的格子背景颜色设置为黄色。
    • 如果 k 等于或大于 allGift.length - 1,说明转到了最后一个奖品格子,将 k 重置为 0,代表开始下一圈,同时圈数 count 加 1,把上一圈最后一个奖品格子的背景颜色变回 cadetblue,当前 k 对应的格子背景颜色设置为黄色。
  2. 滚动速度调整
    • 当圈数 count 小于 3 时,每次将 time 减去 100 毫秒,让滚动速度变快,但最快不超过 100 毫秒。
    • 当圈数 count 大于等于 3 时,每次将 time 加上 100 毫秒,让滚动速度变慢,但最慢不超过 300 毫秒。
  3. 中奖判断与处理
    • 先使用 clearInterval(inter) 清除当前的定时器。
    • 如果随机生成的中奖下标 random 等于当前的 k 且圈数 count 大于 4,说明抽奖停止,弹出提示框显示中奖的奖品名称。
    • 否则,重新设置定时器,继续滚动,直到满足中奖条件。
javascript 复制代码
function autoScroll() {
    //k小于长度 代表转到最后一个元素了   
    if (k < allGift.length - 1) {
        k++;
        //上一个奖品变回原色
        allGift[k - 1].style.backgroundColor = 'cadetblue';
        //当前索引下标变红
        allGift[k].style.backgroundColor = 'yellow';
        //k比长度长的话代表该转第二圈了
    } else {
        //重新让k=0下标, 下一次循环
        k = 0;
        //该转下一圈的话,圈数+1
        count++;
        //上一圈的最后一个奖品变回原色
        allGift[allGift.length - 1].style.backgroundColor = 'cadetblue';
        //当前索引下标变红
        allGift[k].style.backgroundColor = 'yellow';
    }
    if (count < 3) {
        //圈数小于5 ,每次都-100 让他变快变快
        time -= 100;
        //限制条件:最快滚动就是0.2秒
        if (time < 100) {
            time = 100;
        }
        //最外面的否则。就是圈数大于
    } else {
        //让他变慢
        time += 100;
        //限制条件:最慢就是2秒滚动一次
        if (time > 300) {
            time = 300;
        }
    }

    //判断中奖的是啥 和 确认转的圈数
    clearInterval(inter);
    if (random == k && count > 4) {
        //提示用户
        alert('🎉恭喜你,中奖的是🎉:' + '👉👉' + allGift[k].innerHTML + '👈👈');
    } else {
        //清除定时器
        //在设置一个定时器9
        inter = setInterval(autoScroll, time);
    }
}

随机抽奖

随机抽奖即为滚动的格子为随机的。

代码总览

javascript 复制代码
<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<title>抽奖页面</title>
		<style>
			/* 全局样式重置 */
			* {
				margin: 0;
				padding: 0;
			}

			/* 抽奖容器样式 */
			.box {
				background-color: lightgray;
				width: 340px;
				height: 340px;
				position: relative;
			}

			/* 奖品方块样式 */
			.box div {
				background-color: cadetblue;
				width: 100px;
				height: 100px;
				text-align: center;
				line-height: 100px;
			}

			/* 各个奖品方块定位样式 */
			.div1 {
				position: absolute;
				top: 10px;
				left: 10px;
			}

			.div2 {
				position: absolute;
				top: 10px;
				left: 120px;
			}

			.div3 {
				position: absolute;
				top: 10px;
				left: 230px;
			}

			.div4 {
				position: absolute;
				top: 120px;
				left: 230px;
			}

			.div5 {
				position: absolute;
				top: 230px;
				left: 230px;
			}

			.div6 {
				position: absolute;
				top: 230px;
				left: 120px;
			}

			.div7 {
				position: absolute;
				top: 230px;
				left: 10px;
			}

			.div8 {
				position: absolute;
				top: 120px;
				left: 10px;
			}

			/* 抽奖按钮样式 */
			.giftButton {
				position: absolute;
				width: 100px;
				height: 100px;
				top: 120px;
				left: 120px;
				border-radius: 10px;
				background-color: navajowhite;
			}

			#bigAlert {
				display: flex;
				position: fixed;
				/* z-index: 1; */
				/* left: 0; */
				top: 0;
				width: 100%;
				height: 100%;
				/* overflow: auto; */
				background-color: rgba(0, 0, 0, 0.4);
				align-content: center;
			}

			.alertContent {
				display: flex;
				justify-content: space-around;
				align-items: center;
				background-color: white;
				border-radius: 10px;
				/* margin: 15%; */
				/* padding: 20px; */
				/* border: 1px solid #888; */
				width: 300px;
				height: 100px;
				/* margin-left: auto;
				margin-right: auto; */
				margin: auto;

			}

			.buttonAlert {
				padding: 10px;
				color: black;
				background-color: gold;
				border: none;
				border-radius: 10px;
				cursor: pointer;

			}

			.buttonAlert:hover {
				background-color: #609EA0;
				color: blue;
				transition: 0.3s ease;
			}

			.mengban {
				background-color: rgba(0, 0, 0, 0.5);
				width: 100%;
				height: 100%;
				/* z-index: 2; */
				position: absolute;
				top: 0px;
				left: 0px;
				border-radius: 8px;
			}
		</style>
	</head>

	<body>
		<div class="box">
			<div class="div1">电脑</div>
			<div class="div2">手机</div>
			<div class="div3">音响</div>
			<div class="div4">冰箱</div>
			<div class="div5">空调</div>
			<div class="div6">衣柜</div>
			<div class="div7">沙发</div>
			<div class="div8">地毯</div>
			<button class="giftButton">
				<span class="mengban" style="display: none;" readonly></span>
				开始抽奖
			</button>
		</div>

		<div id="bigAlert" style="display: none;">
			<div class="alertContent">
				<span id="alertMessage"></span>
				<button class="buttonAlert" onclick="closeAlert()">确定</button>
			</div>
		</div>

		<script>
			// 显示弹窗的
			function showAlert(a) {
				//先获取到大的div
				let alertDiv = document.getElementById('bigAlert');
				//在获取span标签
				let messageSpan = document.getElementById('alertMessage');
				// 传参(中奖提示)
				// messageSpan.innerHTML = `<span style="color: red;">${a}</span>`;;
				//中奖提示(模板字符串)
				let startIndex = a.indexOf("中奖的是") + "中奖的是".length;
				let highlightedPart = a.slice(startIndex);
				messageSpan.innerHTML = `
				        <span>
				            ${a.slice(0, startIndex)}
				            <span style="color: red; font-weight: bold;">${highlightedPart}</span>
				        </span>
				    `;
				//上面隐藏了 现在在显示出来
				alertDiv.style.display = 'block';
			}
			showAlert('aaaaaaaaaaaa');
			//关闭弹窗的
			function closeAlert() {
				//获取到大div
				let alertDiv = document.getElementById('bigAlert');
				//隐藏
				alertDiv.style.display = 'none';
			}

			// 获取box
			let boxCenter = document.getElementsByClassName('box')[0];
			// 获取boxcenter里的所有的div元素
			let allGift = boxCenter.getElementsByTagName('div');
			// 获取到抽奖按钮,后续绑定点击事件
			let giftButtons = document.getElementsByClassName('giftButton')[0];

			// 充当所有的奖品的下标
			let giftIndex = 0;
			// 旋转时间间隔
			let time = 200;
			// 存定时器的
			let inter;
			// 本次抽奖的随机圈数
			let countTotal;

			let mengban = document.getElementsByClassName('mengban')[0];

			//闪动次数
			let bulingBuling = 0;
			// 点击事件
			giftButtons.onclick = function() {
				bulingBuling = 0;
				// 在数100-200格之间 。随机生成格数
				countTotal = Math.floor(Math.random() * 10 + 1) + 10;
				// 设定时器
				inter = setInterval(autoScroll, time);
				//蒙版显示。标签上隐藏了
				mengban.style.display = 'block';
				//清除点击事件 ,为了抽奖的时候不能再点抽奖按钮
				giftButtons.onclick = null;
			}
			//这个函数会在定时器内被反复调用
			function autoScroll() {
				//每次被调用这个函数 闪动次数+1
				bulingBuling++;
				// 随机选择下一个要变色显示的奖品索引(不按照顺序)
				let nextIndex;
				nextIndex = Math.floor(Math.random() * allGift.length);
				// 循环数组中的每一个元素 让他们颜色统一
				for (let i = 0; i < allGift.length; i++) {
					allGift[i].style.backgroundColor = 'cadetblue';
				}
				// 把 全部div 中挑出来的随机索引下标变黄
				allGift[nextIndex].style.backgroundColor = 'yellow';
				// 判断闪的格,是否等于上面要求的格数
				if (bulingBuling == countTotal) {
					mengban.style.display = 'none';
					//满足就清除定时器
					clearInterval(inter);
					// 提示用户
					showAlert('🎉恭喜你,中奖的是🎉:' + ' ' + allGift[nextIndex].innerHTML);
					//========================重新绑定点击事件============================================
					giftButtons.onclick = function() {
						bulingBuling = 0;
						// 在数100-200格之间 。随机生成格数
						countTotal = Math.floor(Math.random() * 10 + 1) + 10;
						// 设定时器
						inter = setInterval(autoScroll, time);
						mengban.style.display = 'block';
						giftButtons.onclick = null;
					}

				}
			}
		</script>
	</body>

</html>

功能实现差异

第一段代码

  • 滚动规则:奖品格子按照顺序依次滚动,从第一个格子开始,逐个向后滚动,当到达最后一个格子后,重新从第一个格子开始滚动,形成循环滚动的效果。
  • 速度控制:在抽奖开始的前几圈(圈数小于 3),滚动速度逐渐加快,最快达到每 100 毫秒滚动一次;之后滚动速度逐渐变慢,最慢为每 300 毫秒滚动一次。
  • 中奖判断:当随机生成的中奖下标与当前滚动到的格子下标相等,并且已经滚动超过 4 圈时,抽奖停止,弹出中奖提示框。
  • 提示方式 :使用浏览器默认的 alert 函数弹出提示框,显示中奖信息

第二段代码

  • 滚动规则:奖品格子随机闪烁,每次闪烁时,随机选择一个奖品格子改变颜色,不按照顺序进行滚动。
  • 速度控制:滚动速度固定为每 200 毫秒闪烁一次,没有动态调整速度的过程。
  • 中奖判断 :预先随机生成一个 11 - 20 之间的闪烁次数(countTotal),当闪烁次数达到这个随机值时,抽奖停止,弹出中奖提示框。
  • 提示方式 :自定义了一个模态框,通过修改模态框的 display 属性来显示和隐藏,并且对中奖信息中的奖品名称进行了样式处理(红色加粗)。
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰10 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪10 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy11 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom12 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom12 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试