2011-06-06 142 views
1

我正试图编写一个简单的Javascript(jQuery)函数,它可以随机显示6个Divs出11个可能的代码。约有一半的Divs,但它在4和8之间。不一致的Javascript行为(嵌套在while循环中的IF语句)

有谁能告诉我我哪里出错了吗?看来它应该是如此简单,但我完全失去了!

我的代码:

<div class="offer">Offer 1</div> 
<div class="offer">Offer 2</div> 
... snip 
<div class="offer">Offer 11</div> 

<script src="query.min.js" type="text/javascript"></script> 


<script> 
      var changed = 0; 

      while (changed < 6) { 


       $('.offer').each(function(index) { 

        if (changed < 6) { 

         var showOrNot = Math.floor(Math.random() * 2); 

         if (showOrNot == 1) { 

          $(this).addClass('offershow'); 
          changed += 1; 
          $(this).text(changed); //debugging looking for the current value of changed 
         } 


        } 


       }) 


      } 

     </script> 
+0

当我测试它时工作得很好 - http://jsfiddle.net/infernalbadger/LX5xC/它偶尔会少于6次,因为没有检查以确保它不会更改同一个div两次。 – 2011-06-06 15:54:40

+0

你为什么要首先输出div,这不应该是一个serverside/db的工作吗? – Val 2011-06-06 15:55:47

+0

啊,*这*是我没有考虑过的。谢谢!想想卢克可能是对的,但是更准确的解决方案可能会更好。 – 2011-06-06 15:57:06

回答

6

因为就目前的问题是,你有一堆不相关的尝试。如果你有一个有11个球的桶,并且有50%的机会去除每个球,你可以在0到11之间得到任意数量的球。概率向中心倾斜,但是你没有得到6个,恰好是6个每一次。

你想要的是删除六个,正好六个球,任意选择。

尝试更多的东西是这样的:

var offers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; 
for (var i = 0; i < 6; i += 1) { 
    // choose a remaining offer at random 
    var index = Math.floor(Math.random() * offers.length); 

    // retrieve the item being shown 
    var item = $('.offer').eq(offers[index]); 
    item.addClass('offerShow'); 

    // remove this offer from the list of possibilities 
    offers.splice(index, 1); 
} 

编辑:在评论中,OP澄清什么,他真正想要的是采取优惠的任意大小的列表,并显示他们的六人。下面提供的代码说明了需要,而不是原始问题中的严格要求。我将离开原始代码以供参考。

var OFFERS_TO_SHOW = 6; // config, of sorts 

// make sure no offers are shown now 
$('.offer').removeClass('offerShow'); 

// show offers selected at random 
for (var i = 0; i < OFFERS_TO_SHOW; i += 1) { 
    // get a list of offers not already being shown 
    var candidates = $('.offer').not('.offerShow'); 

    // select one from this list at random 
    var index = Math.floor(Math.random() * offers.length); 

    // show this offer by adding the offerShow class 
    candidates.eq(index).addClass('.offerShow'); 
} 
+0

在评论中,我看到很多关于代码运行前的初始状态的讨论。我不认为这是你问题的症结所在,但是你可以简单地通过从一开始就从所有提供中删除类来简单地设置初始状态:'$('。offer')。removeClass('offerShow');' – 2011-06-06 15:59:56

+0

I认为这当然是要走的路。不太清楚如何用jQuery来实现它,但我相信我会找到一种方法。谢谢! – 2011-06-06 16:01:35

+0

今晚晚些时候会阅读并回复您的评论。再次感谢! – 2011-06-06 16:02:34

0

你实际上没有检查选定的div是否已经显示或没有显示。意味着当你循环所有div时,总会有可能将div设置为可见两次。脚本现在认为它是一个新的,并设置改变+ = 1;

尝试增加这样的事情:

if(!$(this).hasClass('offershow')) { 
    [[rest of code here]] 
} 
1

我认为问题是,你不排除你已经设置为显示的div。所以有可能你的代码挑选下一个div来显示选择已经显示的div。如果这有道理?试着改变你的选择.....

$('.offer').not('.offershow').each(........ 

记住addClass不会删除现有的类,所以你原来的选择依然会证明是正确的,即使你已经添加了offershow类。

+0

谢谢 - 这就是我要做的。卢克在评论中首先得到了答案,因此被接受的答案... – 2011-06-06 17:15:18

+0

不用担心,他肯定给出了更详细的回答和答案,你可能已经走了。 :)感谢评论,但! – WesleyJohnson 2011-06-07 02:15:12