为什么这个setTimeout();功能不像我认为应该工作?

时间:2014-08-04 19:49:10

标签: javascript jquery settimeout

我想制作匹配卡类游戏,点击后一次显示2张卡片。如果它们是相同的,它们将变为非活动状态,如果它们不相同,它们将被再次覆盖。

这是一个实现,其中卡片在点击后1.5秒被揭开

$(document).on("click", "div.card.covered", function(){    
    if( $('div.card.uncovered').length < 2 ){
        uncover_card(this);
    }       
    if( $('div.card.uncovered').length == 2 ){
        var uncovered_cards = new Array();          
        $('div.card.uncovered').each(function(){
            uncovered_cards.push( $(this).attr("class") );
        });

        if( uncovered_cards[0] == uncovered_cards[1]){
            setTimeout(function(){
                $('div.card.uncovered').addClass("matched");
                $('div.card.uncovered').removeClass("uncovered");
                //uncover_card(this);
            },1000);                
        }else{
            setTimeout(function(){
                $('div.card.uncovered').addClass("covered");
                $('div.card.uncovered').removeClass("uncovered");
                //uncover_card(this);
            },1000);
        }
    }
});

http://jsfiddle.net/Lf8cE/2/

如果你这样做,它将按预期工作。

然而,如果你点击2,然后点击第三个就像疯了一样等待它们变为非活动状态或再次掩盖,这个第三张卡将在对更改后不久,也会改为同样的状态这对。

为什么会发生这个错误?!

3 个答案:

答案 0 :(得分:1)

@KevinB在评论中提到的问题是,每次单击时都会添加额外的超时。当第一个超时触发时,它会从两张卡中删除uncovered类。现在,因为您快速点击,您会发现另一张卡片。但是,你的第二次(或第三次,第四次等)超时会在任何未被覆盖的牌上发射并作用,从而影响这张新发现的牌。

最简单的解决方法是将第二个if移到第一个if( $('div.card.uncovered').length < 2 ) { uncover_card(this); if( $('div.card.uncovered').length == 2 ) { var uncovered_cards = new Array(); $('div.card.uncovered').each(function(){ uncovered_cards.push( $(this).attr("class") ); }); if( uncovered_cards[0] == uncovered_cards[1]) { setTimeout(function(){ $('div.card.uncovered').addClass("matched"); $('div.card.uncovered').removeClass("uncovered"); //uncover_card(this); },1000); } else { setTimeout(function(){ $('div.card.uncovered').addClass("covered"); $('div.card.uncovered').removeClass("uncovered"); //uncover_card(this); },1000); } } } 内,以便只触发一次。

{{1}}

http://jsfiddle.net/Lf8cE/4/

答案 1 :(得分:0)

它正在发生,因为你正在添加课程&#34;匹配&#34;到每个匹配div.card.uncovered选择器的卡。这包括同时点击的任何卡片。如果您缓存了第一个&#34;未覆盖&#34;元素,然后你可以在匹配完成后对它们进行操作。这是一个工作片段:

    var uncovered_cards = [];
    var els = $('div.card.uncovered');
    els.each(function(){
        uncovered_cards.push( $(this).attr("class") );
    });

    if( uncovered_cards[0] == uncovered_cards[1]){
        setTimeout(function(){
            els.addClass("matched");
            els.removeClass("uncovered");
            //uncover_card(this);
        },1000);            
    }

答案 2 :(得分:0)

这里的问题是使用setTimeout函数。

基本上,在超时间隔结束时,您正在寻找带有uncovered类的所有卡,并覆盖它们或匹配它们。通过点击第三张卡片&#34;像疯了一样#34;在uncovered能够查询setTimeout之前,您设法将第三张卡设置为$('div.card.uncovered'),因此它匹配/覆盖所有三张uncovered卡。< / p>

解决方案是通过引用匹配/覆盖两张卡,而不是在超时结束时再次查询它们。

这样的事情:

setTimeout(function(){
    uncovered_cards[0].addClass("matched");
    uncovered_cards[0].removeClass("uncovered");

    uncovered_cards[1].addClass("matched");
    uncovered_cards[1].removeClass("uncovered");
},1000);

请注意:我没有测试过上面的代码,它可能无法正常工作。它只是用来证明这个概念。