Inconsistent Javascript behaviour (IF statement nested in while loop)
I'm trying to write a simple Javascript(jQuery) function that randomly displays 6 Divs out of a possible 11. The code sort-of-works, it does randomly display around about half of the Divs, but it varaies between 4 and 8.
Can anyone tell me where I'm going wrong? It seems it should be so simple yet I'm completely lost!
My code:
<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>
The problem as it stands now is that you have a bunch of unrelated attempts. If you have a bucket with 11 balls and have a 50% chance to remove each ball, you could end up with any number of balls between 0 and 11. Probability is skewed toward the center, but you don't get six and exactly six each time.
What you want is to remove six, and exactly six, balls, selected arbitrarily.
Try something more like this:
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);
}
EDIT: In the comments, the OP clarified that what he really wants is to take an arbitrarily-sized list of offers and show six of them. The code provided below addresses that need, rather than the strict request in the original question. I'm leaving the original code for reference.
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');
}
I think the problem is that you're not excluding divs that you've already set to show. So it's possible that your code to pick the next div to show is choosing one that's already been shown. If that makes sense? Trying changing your selector.....
$('.offer').not('.offershow').each(........
Keep in mind that addClass doesn't remove the existing classes, so your original selector will still prove true even though you've added the offershow class.
You're actually not checking wheter the selected div is already shown or not. Means when you're looping through all divs, there is always a possibility of setting a div visible twice. The script now thinks it was a new one and sets changed += 1;
Try adding something like this:
if(!$(this).hasClass('offershow')) {
[[rest of code here]]
}
精彩评论