半小时撸一个抽奖程序

84

需求总是很紧急,昨天正在开会收到人力需求,有时间做个抽奖吗?(now 下午四点12,年会五点开始。)还没能等我拒绝,人事又补了一句做不出来我们就不抽奖了,我擦瞬间感觉要是搞不出来会被兄弟们捅死的节奏,默默的删除了没时间做的消息,重新写了四个字名单给我。

还好去年前年都是我搞得很庆幸没被当场打脸,重启去年程序(需要收集全员头像并ps)时间显然不够,庆幸的是还有点经验,会议结束时间已经四点半了。

好了不扯淡了开始干活吧!

先屡一下思路

1、好看是好看不了了,别指望没设计没时间程序员搞出来的效果。
2、样式开始按钮、停止按钮、人员名单别列表、抽中名单列表。
3、点击开始,首先乱序名单列表保证每次抽奖列表顺序不一样,防止他们怀疑我作弊搞权重(就TM半小时哪有时间搞权重)时间紧任务重,直接用的lodash shuffle方法来乱序视图
4、随机数是肯定要有的,每隔200ms随机一个从0到人员个数(数组长度随机整数)
5、抽中人员和没抽中人员分两个数组存入localStorage,防止抽奖过程中刷新页面,纯静态不存本地那场面就尴尬了每次刷新完如果本次存储了从本地获取人员列表和中奖名单
6、点击end选中当前随机数在页面上高亮显示。

接下来看整体实现代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>2019抽奖程序</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://lib.baomitu.com/lodash.js/4.14.1/lodash.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .list-complete-item {
            transition: all 1s;
            display: inline-block;
            border: 1px solid #ccc;
            width: 80px;
            height: 80px;
            line-height: 80px;
            text-align: center
        }
        
        .draw-bg {
            background-color: red;
            transform: scale(1.5)
        }
        
        .list-complete-enter,
        .list-complete-leave-to {
            opacity: 0;
            transform: translateY(30px);
        }
        
        .list-complete-leave-active {
            position: absolute;
        }
        
        .draw {
            height: 100px;
        }
        
        button {
            padding: 5px 10px;
            margin: 20px;
        }
        
        li {
            float: left
        }
        
        .draw-list span {
            display: inline-block;
            padding: 10px;
            background: red;
            color: #fff
        }
    </style>

</head>

<body>
    <div id="list-complete-demo" class="demo">
        <button v-on:click="start">start</button>
        <button v-on:click="end">end</button>
        <div class="draw-list">
            <span v-for="item in target">{{item}}</span>
        </div>
        <transition-group name="list-complete" tag="p">
            <span v-for="item in arrList" v-bind:key="item" class="list-complete-item" :class="{'draw-bg': item == value}">
                {{ item }}
            </span>
        </transition-group>
    </div>
    <script>
        new Vue({
            el: '#list-complete-demo',
            data: {
                arrList: [
                    "张三",
                    "李四",
                    "王五",
                    "赵六",
                    "陈七",
                    "张扒",
                    "李十四",
                    "王十五",
                    "赵十六",
                    "陈十七",
                    "张二三",
                    "李二四",
                    "王二五",
                    "赵二六",
                    "陈二七",
                    "张二扒",
                    "李三四",
                    "王三五",
                    "赵三六",
                    "陈三七"
                ],
                target: [],
                index: -1,
                timer: null,
                value: '',
                status: true
            },
            mounted() {
                if (!localStorage.getItem('initData')) {
                    localStorage.setItem('initData', JSON.stringify(this.arrList))
                } else {
                    this.arrList = JSON.parse(localStorage.getItem('initData'))
                }
                if (localStorage.getItem('drawList')) {
                    this.target = JSON.parse(localStorage.getItem('drawList'))
                }

            },
            methods: {
                start() {
                    if (this.status) {
                        if (this.index != -1) {
                            this.arrList.splice(this.index, 1)
                            localStorage.setItem('initData', JSON.stringify(this.arrList))
                        }
                        this.shuffle()
                        setTimeout(() => {
                            this.recursive()
                        }, 800)
                        this.status = !this.status
                    }
                },
                randomIndex: function() {
                    this.index = Math.floor(Math.random() * this.arrList.length)
                    return this.index
                },
                remove: function() {
                    this.arrList.splice(this.randomIndex(), 1)
                },
                shuffle: function() {
                    this.arrList = _.shuffle(this.arrList)
                },
                recursive() {
                    clearTimeout(this.timer)
                    this.timer = setTimeout(() => {
                        this.value = this.arrList[this.randomIndex()]
                        this.recursive()
                    }, 200)
                },
                end() {
                    if (this.status) {
                        return
                    }
                    clearTimeout(this.timer)
                    this.index = this.randomIndex()
                    this.value = this.arrList[this.index]
                    this.target.push(this.value)
                    localStorage.setItem('drawList', JSON.stringify(this.target))
                    this.status = !this.status
                }
            }
        })
    </script>
</body>

</html>

体验下效果
Kapture-2019-01-30-at-16.06.34.gif

需求搞定,经现场测试目前没发现什么问题!如有疑问随时回复留言!


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

19 条评论
wang_Agoni · 1月31日

半个小时,我可能还在百度

+2 回复

0

@wangbinze 难道Google不才是程序员的最爱吗?

我是一个前端 作者 · 1月31日
0

@我是一个前端 一时打字太快,习惯了。Google大法好

wang_Agoni · 1月31日
羊爸爸 · 1月31日

可重复中奖?

+1 回复

0

@羊爸爸 逻辑是不可以的,中奖以后会在人员list删除掉

我是一个前端 作者 · 1月31日
chenxiao · 2月18日

如果执行很多次全部的中奖了,后面还可以点击start(),end();这个可以改进,虽然是极端下的

+1 回复

0

说的对,程序员需要严谨,代码需要健壮!

我是一个前端 作者 · 2月18日
ouyida3 · 1月31日

厉害。半小时给我,估计还在想要做成啥样子呢

回复

tkpromise · 1月31日

老司机……

回复

guanhui07 · 1月31日

可重复中奖?

回复

0

@guanhui07 不可以 如果确认可以可以反馈我 谢谢

我是一个前端 作者 · 1月31日
kumfo · 1月31日

应该给我加个名字,我坐飞机来领。

回复

董广明 · 2月12日

今年试试

回复

kopi · 2月13日

厉害

回复

JS小白 · 2月14日

流弊~~~

回复

answer · 2月14日

看到上面有问重复中奖的,自己研究了下代码,发现如果在抽取一个人,刷新页面,在点击开始按钮开始抽奖,会发现之前抽取的那个人还在抽取的列表中,没有被移除出去。
start()方法中(注释部分是楼主原来的代码,我改成了下面这样)
// if (this.index != -1) {

        //   this.arrList.splice(this.index, 1)
        //   localStorage.setItem('initData', JSON.stringify(this.arrList))
        // }
        if (localStorage.getItem('value')) {
          this.arrList.splice(this.arrList.indexOf(localStorage.getItem('value')), 1)
          localStorage.setItem('initData', JSON.stringify(this.arrList))
        }

end()方法中

     ....
     this.value = this.arrList[this.index]
     // 将中奖者的名字存入localstorage,以防止刷新页面带来的bug
      localStorage.setItem('value', this.value)
      .....

一点鄙见,希望共同讨论

回复

0

没太明白,本地存储已经存了已中奖名单和未中奖名单。稍后我把整个html贴出来。欢迎吐槽!

我是一个前端 作者 · 2月14日
0

@我是一个前端 在抽取一个人之后,index这时是打乱后中奖人的索引,再点击start按钮时才会把它从抽奖人的数组中去移除,但是如果此时刷新页面的话,这个index会消失,所以在刷新页面后点击start按钮开始抽奖时,不会把之前中奖人从抽奖人数组中移除。。。不知道我测试的结果对不对

answer · 2月15日
0

@answer 大概明白你的意思了,下午测一下!

我是一个前端 作者 · 2月15日
载入中...