用js做抽奖效果时,显示不正常,希望大神指点。

今天在用js做一个简单的抽奖效果时显示有问题,代码在下面,希望大神指点

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>抽奖</title>
        <style media="screen">
            *{
                margin: 0;
                padding: 0;
            }
            .box{
                width: 600px;
                height: 300px;
                font-size: 0;
                margin: 200px auto;
            }
            span{
                display: inline-block;
                float: left;
                width: 200px;
                height: 100px;
                line-height: 100px;
                text-align: center;
                color: #fff;
                background-color: #009933;
                font-size: 16px;
            }
            #btn{
                background-color: #3399FF;
            }
            .active{
                background-color: #CC0033;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <span id="c1">一等奖</span>
            <span id="c2">二等奖</span>
            <span id="c3">三等奖</span>
            <span id="c8">谢谢参与</span>
            <span id="btn">点击抽奖</span>
            <span id="c4">一等奖</span>
            <span id="c7">三等奖</span>
            <span id="c6">二等奖</span>
            <span id="c5">谢谢参与</span>
        </div>
        <script type="text/javascript" src="jquery-1.12.1.js"></script>
        <script type="text/javascript">
            var arr = ['c1','c2','c3','c4','c5','c6','c7','c8','c1','c2','c3','c4','c5','c6','c7','c8'], timer;
            function _loop(){
                for(var i = 0, len = arr.length; i < len; i++){
                    if (i == 0) {
                        $('#'+arr[0]).addClass('active');
                    }
                    if( i > 0 && i < 15 ){
                        $('#'+arr[i-1]).removeClass('active');
                        $('#'+arr[i]).addClass('active');
                    }
                    if (i == 15) {
                        clearTimeout(timer);
                    }
                }
            }
            timer = setTimeout(function(){
                _loop();
            },500);
        </script>
    </body>
</html>
阅读 3.2k
3 个回答

你想要的是什么效果?外围一圈奖项转圈依次亮起,亮完一圈之后结束吗?

补充答案:
首先这段代码肯定是实现不了你要的效果。
你设置了一个数组储存对应dom。
然后新建了一个函数_loop,循环了一遍数组,对各种情况进行了判断。(第二种情况也应该是<=15,否则最后一项永远不会active)。
最后用了一个setTimeout定时器,效果是500ms后执行_loop,而_loop就是一个瞬间完成的循环,最后i=14时active了arr[14]。

你自己实际写的时候肯定还会遇到很多问题,最有可能的是把setTimeout放到for循环中之后,发现i没法传递到计时器里,这就是个闭包或者说块状作用域的问题,相关资料很多,看完答案一定要搞懂。

用闭包解决:

var arr = ['c1','c2','c3','c4','c5','c6','c7','c8','c1','c2','c3','c4','c5','c6','c7','c8'], timer;

var loop = function (i) {
    console.log(i)
    if (i === 0) {
        $('#'+arr[0]).addClass('active');
    }
    if( i > 0 && i <= 15 ){
        $('#'+arr[i-1]).removeClass('active');
        $('#'+arr[i]).addClass('active');
    }
};

for (var i = 0; i < arr.length; i++) {
    (function (a) {
        setTimeout(function () {
            loop(a);
        }, 500 * i);
    })(i);
};

闭包解决的也是块状作用域的问题,在es6标准下,可以用更语义化的let解决:

// es6
var loop = function (i) {
    console.log(i)
    if (i === 0) {
        $('#'+arr[0]).addClass('active');
    }
    if( i > 0 && i <= 15 ){
        $('#'+arr[i-1]).removeClass('active');
        $('#'+arr[i]).addClass('active');
    }
};
for (let i = 0; i < arr.length; i++) {
    setTimeout(function () {
        loop(i);
    }, 500 * i)
};

在你的代码的基础上改了一下,你自己对比一下修改的地方吧。;)
总体来说代码还是有点不忍直视的,加油学习吧。

<html>
    <head>
        <meta charset="utf-8">
        <title>抽奖</title>
        <style media="screen">
            *{
                margin: 0;
                padding: 0;
            }
            .box{
                width: 600px;
                height: 300px;
                font-size: 0;
                margin: 200px auto;
            }
            span{
                display: inline-block;
                float: left;
                width: 200px;
                height: 100px;
                line-height: 100px;
                text-align: center;
                color: #fff;
                background-color: #009933;
                font-size: 16px;
            }
            #btn{
                background-color: #3399FF;
            }
            .active{
                background-color: #CC0033;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <span id="c1">一等奖</span>
            <span id="c2">二等奖</span>
            <span id="c3">三等奖</span>
            <span id="c8">谢谢参与</span>
            <span id="btn">点击抽奖</span>
            <span id="c4">一等奖</span>
            <span id="c7">三等奖</span>
            <span id="c6">二等奖</span>
            <span id="c5">谢谢参与</span>
        </div>
        <script type="text/javascript" src="jquery-1.12.1.js"></script>
        <script type="text/javascript">
            var arr = ['c1','c2','c3','c4','c5','c6','c7','c8','c1','c2','c3','c4','c5','c6','c7','c8'], timer;
            function _loop(i){
                    if (i == 0) {
                        $('#'+arr[0]).addClass('active');
                    }
                    if( i > 0 && i < 15 ){
                        $('#'+arr[i-1]).removeClass('active');
                        $('#'+arr[i]).addClass('active');
                    }
                    if (i == 15) {
                        clearTimeout(timer);
                    }else{
                        timer = setTimeout(function(){
                            _loop(i+1);
                        },500);
                    }
            }
            timer = setTimeout(function(){
                _loop(0);
            },500);
        </script>
    </body>
</html>

使用setTimeout只会被调用一次,想做成动画效果需要重复调用。

写了一个能跑起来的效果,可以看下
图片描述

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>抽奖</title>
        <style media="screen">
            *{
                margin: 0;
                padding: 0;
            }
            .box{
                width: 600px;
                height: 300px;
                font-size: 0;
                margin: 200px auto;
            }
            span{
                display: inline-block;
                float: left;
                width: 200px;
                height: 100px;
                line-height: 100px;
                text-align: center;
                color: #fff;
                background-color: #009933;
                font-size: 16px;
                -webkit-transition: all .3s ease-out;
                transition: all .3s ease-out;
            }
            #btn{
                background-color: #3399FF;
                cursor: pointer;
            }
            #btn.active{
                background-color: #aaa;
            }
            .active{
                background-color: #CC0033;
            }
        </style>
    </head>
    <body>
        <div class="box">
            <span id="c1">一等奖</span>
            <span id="c2">二等奖</span>
            <span id="c3">三等奖</span>
            <span id="c8">谢谢参与</span>
            <span id="btn">点击抽奖</span>
            <span id="c4">一等奖</span>
            <span id="c7">三等奖</span>
            <span id="c6">二等奖</span>
            <span id="c5">谢谢参与</span>
        </div>
        <script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
        <script type="text/javascript">
            $('#btn').click(function() {
                var self = $(this);
                if(self.hasClass('active')) {
                    return;
                } else {
                    self.addClass('active');
                    var i = 0;
                    var j = 0;
                    var max = parseInt(Math.random() * 10 + 9);
                    var running = setInterval(function() {
                        i++;
                        j++;
                        if(j == max) {
                            clearInterval(running);
                            alert($('[id^="c"].active').text());
                            self.removeClass('active');
                            i= j = 0;
                        } else if(i%9==0) {
                            i=0;
                        }
                        $('#c'+i).addClass('active').siblings(':not(#btn)').removeClass('active');
                    }, 100);
                }
            });
        </script>
    </body>
</html>
推荐问题