2011-06-06 3 views
1

J'essaye d'écrire une fonction Javascript (jQuery) simple qui affiche aléatoirement 6 Divs sur un possible 11. Le code sort-of-works, il affiche aléatoirement environ la moitié des Divs, mais il varaies entre 4 et 8.Comportement Javascript incohérent (instruction IF imbriquée dans while loop)

Quelqu'un peut-il me dire où je vais mal? Il semble qu'il devrait être si simple mais je suis complètement perdu!

Mon 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> 
+0

Fonctionne plutôt bien quand je le teste - http://jsfiddle.net/infernalbadger/LX5xC/ Il fera occasionnellement moins de 6 car il n'y a pas de vérification pour s'assurer qu'il ne change pas la même div deux fois. –

+0

pourquoi produisez-vous les divs en premier lieu, ne devrait-ce pas être un travail de sideside/db? – Val

+0

Ah, * c'est * ce que je n'avais pas expliqué. Je vous remercie! Pensez que Luke a probablement raison et qu'une solution plus «exacte» pourrait être meilleure. –

Répondre

6

Le problème tel qu'il se présente est maintenant que vous avez un tas de tentatives non apparentées. Si vous avez un seau avec 11 balles et que vous avez 50% de chance de retirer chaque balle, vous pourriez vous retrouver avec un nombre quelconque de balles entre 0 et 11. La probabilité est faussée vers le centre, mais vous n'obtenez pas six et exactement six chaque fois.

Ce que vous voulez est d'enlever six, et exactement six, balles, choisis arbitrairement.

Essayez quelque chose comme ceci:

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: Dans les commentaires, l'OP a précisé que ce qu'il veut vraiment est de prendre une liste arbitraire de la taille des offres et montrer six d'entre eux. Le code fourni ci-dessous répond à ce besoin plutôt qu'à la demande stricte de la question initiale. Je laisse le code original pour référence.

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

Dans les commentaires, je vois beaucoup de discussion sur l'état initial avant que ce code ne s'exécute. Je ne pense pas que ce soit le cœur de votre problème, mais vous pouvez facilement définir l'état initial simplement en supprimant la classe de toutes les offres au début: '$ ('. Offer'). RemoveClass ('offerShow');' –

+0

I pense que c'est certainement le chemin à parcourir. Je ne sais pas trop comment l'implémenter avec jQuery, mais je suis sûr que je trouverai un moyen. Je vous remercie! –

+0

lira et répondra à votre commentaire plus tard ce soir. Merci encore! –

0

Vous n'êtes pas en train de vérifier si la div sélectionnée est déjà affichée ou non. Cela signifie que lorsque vous parcourez toutes les divs, il est toujours possible de définir une div deux fois. Le script pense maintenant que c'était un nouveau jeu et qu'il a changé + = 1;

Essayez d'ajouter quelque chose comme ceci:

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

Je pense que le problème est que vous n'êtes pas hors divs que vous avez déjà configuré pour afficher. Il est donc possible que votre code sélectionne le div suivant pour en choisir un qui a déjà été affiché. Si ça a du sens? Essayer de changer votre sélecteur .....

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

Gardez à l'esprit que addClass ne supprime pas les classes existantes, de sorte que votre sélecteur d'origine sera toujours prouver vrai même si vous avez ajouté la classe offershow.

+0

Merci - c'est ce que je vais avec. Luke est arrivé le premier dans un commentaire d'où la réponse acceptée ... –

+0

Pas de soucis, il a certainement donné une réponse plus détaillée et une réponse et vous auriez pu aller de toute façon. :) Merci d'avoir commenté cependant! – WesleyJohnson

Questions connexes