九格宫抽奖相信大家都玩过, 今天就用 JavaScript 写个九宫格抽奖玩玩. 让中奖不再是梦!
1. 预览效果
image
效果图为屏幕录制软件生成, 以至于出现滚动不连贯. 实际运行中不会出现不连贯的滚动效果
2. 完整代码
代码可直接复制运行查看效果(图片记得更换)
- <!DOCTYPE html>
- <HTML>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>
- JavaScript 实现九宫格抽奖
- </title>
- <style>
- body{ background-color: #2c9afc; } #container { width: 330px; height:
- 340px; margin: 10% auto; border: 7px solid #99d4ff; border-radius: 10px;
- padding: 2%; } #list { width: 330px; height: 340px; list-style: none; margin:
- 0; padding: 0; } #list li, #list span { width: 100px; height: 100px; float:
- left; text-align: center; line-height: 100px; position: relative; background-color:
- #384f9a; margin: 1.4%; border-radius: 5px; } #list li img{ display: block;
- width: 100%; height: 100%; } #list li .mask{ width: 100%; height: 100%;
- position: absolute; left:0; top:0; background: url(images/mask.PNG) no-repeat;
- background-size: cover; display: none; } #list span:hover { cursor: pointer;
- color: orange; font-size: 18px; } #list .active .mask{ display: block;
- } #message { line-height: 32px; color: #9a9a9a; text-align: center; position:absolute;
- left: 50%; top: 50px; width: 300px; height: 50px; margin-left: -150px;
- display: none; background: #000; color: #fff; }
- </style>
- </head>
- <body>
- <h3 style="text-align:center;margin-top: 10%;color:white">
- JavaScript 实现九宫格抽奖
- </h3>
- <div id="container">
- <ul id="list">
- <!-- img 标签放奖品图片 -->
- <!-- mask 类为抽奖滚动起来的标记 -->
- <li>
- <img src="images/1.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/2.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/3.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/4.png" />
- <div class="mask">
- </div>
- </li>
- <span id="startbutton" onclick="startlottery()" style="background-color:#ff3a59;color:white;font-size: 20px;">
- 开始抽奖
- </span>
- <li>
- <img src="images/5.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/6.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/7.png" />
- <div class="mask">
- </div>
- </li>
- <li>
- <img src="images/8.png" />
- <div class="mask">
- </div>
- </li>
- </ul>
- <div id="message">
- </div>
- <!-- 获奖信息展示 -->
- </div>
- </body>
- <script type="text/javascript">
- var container = document.getElementById('container'),
- li = container.getElementsByTagName('li'),
- span = document.getElementById('startbutton'),
- message = document.getElementById('message'),
- timer = null;
- bReady = true; // 定义一个抽奖开关
- var prize = [0, 1, 2, 4, 7, 6, 5, 3]; // 奖品 li 标签滚动的顺序
- var num = 0; //num 用来存放得到的随机函数, 也就是抽中的奖品
- // 开始抽奖
- function startlottery() {
- if (bReady) { // 当抽奖开关为 true 的时候, 可点击抽奖
- message.style.display = "none"; // 将获奖信息 div 隐藏(以防止上次抽奖信息还显示)
- span.style.background = "#ada7a8";
- bReady = false; // 抽奖开关设为 false 处于抽奖中 即不能点击抽奖
- num = getrandomnum(1, 9) // 得到一个随机数(即奖品)
- // console.log(num)
- startinit(num); // 执行抽奖初始化
- }
- }
- // 抽中的奖品 返回 1-9 的整数, 包含 1, 不包含 9
- function getrandomnum(n, m) {
- return parseInt((m - n) * Math.random() + n);
- }
- // 抽奖初始化
- function startinit(num) {
- var i = 0; // 定义一个 i 用来计算抽奖跑动的总次数
- var t = 200; // 抽奖跑动的速度 初始为 200 毫秒
- var rounds = 5; // 抽奖转动的圈数
- var rNum = rounds * 8; // 标记跑动的次数(这是一个条件判断分界线)
- timer = setTimeout(startscroll, t); // 每 t 毫秒执行 startscroll 函数
- // 抽奖滚动的函数
- function startscroll() {
- // 每次滚动抽奖将所有 li 的 class 都设为空
- for (var j = 0; j < li.length; j++) {
- li[j].className = '';
- }
- var prizenum = prize[i % li.length]; // 通过 i 余 8 得到此刻在 prize 数组中的数字, 该数字就是 mask 标记出现的位置
- li[prizenum].className = "active";
- i++;
- if (i < rNum - 8) { // 当 i 小于转 (rNum-8 次) 的数量, t 不变还是 200 毫秒
- timer = setTimeout(startscroll, t); // 继续执行抽奖滚动
- } else if (i >= rNum - 8 && i < rNum + num) {
- //t 时间变长, 此时计时器运行速度降低, 同时标签刷新速度也降低
- t += (i - rNum + 8) * 5;
- timer = setTimeout(startscroll, t); // 继续执行抽奖滚动
- }
- if (i >= rNum + num) { // 当 i 大于转 rNum 加随机数字 num 次计时器结束, 出现提示框提示中奖信息
- if (num == 1) {
- message.innerHTML = "恭喜你中了耳机";
- } else if (num == 2) {
- message.innerHTML = "恭喜你中了 iPad";
- } else if (num == 3) {
- message.innerHTML = "感谢参与";
- } else if (num == 4) {
- message.innerHTML = "恭喜你中了洋娃娃";
- } else if (num == 5) {
- message.innerHTML = "恭喜你中了红色鞋子";
- } else if (num == 6) {
- message.innerHTML = "恭喜你中了白色手机";
- } else if (num == 7) {
- message.innerHTML = "恭喜你中了黑色手机";
- } else if (num == 8) {
- message.innerHTML = "恭喜你中了蓝色鞋子";
- }
- var timer2 = null;
- timer2 = setTimeout(function() {
- message.style.display = "block"; // 奖品展示的信息为显示状态
- span.style.background = "#ff3a59";
- clearTimeout(timer2);
- },
- 1000);
- bReady = true; // 当计时器结束后让 span 标签变为抽奖状态
- clearTimeout(timer);
- }
- }
- }
- </script>
- </HTML>
3. 代码分析
1. prize var prize = [0,1,2,4,7,6,5,3];// 奖品 li 标签滚动的顺序
数组 prize 中的数字就是 li 标签对应的索引值, 由于是九宫格抽奖, 因此抽奖滚动的顺序并不是按 li 标签的索引顺序, 以下是 li 标签实际滚动的顺序图分析:
image
2. getrandomnum(1,9) // 抽中的奖品 返回 1-9 的整数, 包含 1, 不包含 9 function getrandomnum(n, m) { return parseInt((m - n) * Math.random() + n); }
因为只有 8 个奖品, 所以得到的随机整数不包含 9
3. 变量 i,rounds,rNum
var i = 0; // 定义一个 i 用来计算抽奖跑动的总次数 var rounds = 5; // 抽奖转动的圈数 var rNum = rounds*8; // 标记跑动的次数(这是一个条件判断分界线)
i 是用来计算 li 标签滚动的次数, 滚动一次加 1;
rounds 及 rNum 用来让滚动抽奖变慢及停止的判断条件;
4. prizenum var prizenum = prize[i%li.length]; // 通过 i 余 8 得到此刻在 prize 数组中的数字, 该数字就是 mask 标记出现的位置 li[prizenum].className = "active";
i%li.length 为 i 除以 li 标签长度得到的余数(始终为 0-7 范围的整数), 放进 prize 数组中, 得到的 prizenum 数字就是当前滚动到的 li 标签索引值
来源: http://www.jianshu.com/p/1ddbde80a61d