Javascript行为不一致(如果语句嵌套在while循环中)

Javascript行为不一致(如果语句嵌套在while循环中),javascript,jquery,random,while-loop,Javascript,Jquery,Random,While Loop,我正在尝试编写一个简单的Javascript(jQuery)函数,它随机显示11个div中的6个div。代码可以工作,它确实随机显示大约一半的div,但是它在4到8之间变化 谁能告诉我哪里出了问题?看起来应该很简单,但我完全迷路了 我的代码: <div class="offer">Offer 1</div> <div class="offer">Offer 2</div> ... snip <div class="offer">Offe

我正在尝试编写一个简单的Javascript(jQuery)函数,它随机显示11个div中的6个div。代码可以工作,它确实随机显示大约一半的div,但是它在4到8之间变化

谁能告诉我哪里出了问题?看起来应该很简单,但我完全迷路了

我的代码:

<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>
Offer 1
提议2
... 剪
报价11
var=0;
而(变化<6){
$('.offer')。每个(函数(索引){
如果(更改<6){
var showOrNot=Math.floor(Math.random()*2);
如果(showOrNot==1){
$(this.addClass('offershow');
变化+=1;
$(this).text(已更改);//正在调试以查找已更改的当前值
}
}
})
}

目前的问题是,您有许多不相关的尝试。如果你有一个装有11个球的桶,并且有50%的机会将每个球移走,那么你最终可能会得到0到11之间的任意数量的球。概率是向中心倾斜的,但你不可能每次都得到六,也不可能每次都是六

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

尝试类似以下内容:

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);
}
if(!$(this).hasClass('offershow')) {
    [[rest of code here]]
}
var提供=[1,2,3,4,5,6,7,8,9,10,11];
对于(变量i=0;i<6;i+=1){
//随机选择剩余的报价
var index=Math.floor(Math.random()*offers.length);
//检索正在显示的项目
var项目=$('.offer').eq(offers[index]);
item.addClass(“报价单”);
//从可能性列表中删除此报价
接头(索引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');
}
var提供了\u到\u SHOW=6;//各种各样的
//确保现在不显示任何优惠
$('.offer').removeClass('offerShow');
//显示随机选择的报价
对于(变量i=0;i<提供给显示;i+=1){
//获取尚未显示的报价列表
var候选者=$('.offer')。而不是('.offerShow');
//从该列表中随机选择一个
var index=Math.floor(Math.random()*offers.length);
//通过添加offerShow类来显示此报价
eq(index).addClass('.offerShow');
}

目前的问题是,您有许多不相关的尝试。如果你有一个装有11个球的桶,并且有50%的机会将每个球移走,那么你最终可能会得到0到11之间的任意数量的球。概率是向中心倾斜的,但你不可能每次都得到六,也不可能每次都是六

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

尝试类似以下内容:

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);
}
if(!$(this).hasClass('offershow')) {
    [[rest of code here]]
}
var提供=[1,2,3,4,5,6,7,8,9,10,11];
对于(变量i=0;i<6;i+=1){
//随机选择剩余的报价
var index=Math.floor(Math.random()*offers.length);
//检索正在显示的项目
var项目=$('.offer').eq(offers[index]);
item.addClass(“报价单”);
//从可能性列表中删除此报价
接头(索引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');
}
var提供了\u到\u SHOW=6;//各种各样的
//确保现在不显示任何优惠
$('.offer').removeClass('offerShow');
//显示随机选择的报价
对于(变量i=0;i<提供给显示;i+=1){
//获取尚未显示的报价列表
var候选者=$('.offer')。而不是('.offerShow');
//从该列表中随机选择一个
var index=Math.floor(Math.random()*offers.length);
//通过添加offerShow类来显示此报价
eq(index).addClass('.offerShow');
}

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

尝试添加如下内容:

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);
}
if(!$(this).hasClass('offershow')) {
    [[rest of code here]]
}

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

尝试添加如下内容:

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);
}
if(!$(this).hasClass('offershow')) {
    [[rest of code here]]
}

我认为问题在于,你没有排除你已经设置好要显示的div。因此,选择下一个要显示的div的代码可能是选择了一个已经显示的div。这有意义吗?正在尝试更改选择器

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

请记住,addClass不会删除现有的类,因此,即使您添加了offershow类,您的原始选择器仍将被证明是正确的。

我认为问题在于您没有排除已设置为显示的div。因此,选择下一个要显示的div的代码可能是选择了一个已经显示的div。这有意义吗?正在尝试更改选择器

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

请记住,addClass不会删除现有的类,因此,即使您添加了offershow类,您的原始选择器仍将被证明是正确的。

在我测试它时效果很好-它偶尔会做不到6次,因为没有检查来确保它不会更改同一个div两次。为什么您首先要输出div,这不应该是服务器端/db作业吗?啊,这就是为什么