JordanBarber
JordanBarber

Reputation: 2101

Select random 'eq' of div but different div each time

I am selecting a random instance of a class. I can repeat the same instance, but just not back to back. For example, I can select the 2nd instance, 3rd instance, 2nd instance but not 2nd instance, 2nd instance, 3rd instance Here's my code:

<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>

Javascript:

DevRotator = {
        initialDev: '.featured-dev.initial',
        notInitial: '#loaded-devs .featured-dev',
        init: function() {
            setInterval(this.changeDevs.bind(this), 3000);
        },
        changeDevs: function() {

            var devToFlip = [Math.floor(Math.random()*$(this.initialDev).length)];

            $(this.initialDev).removeClass('animated flipInX');
        var randomInitial = $(this.initialDev).eq(devToFlip);
        randomInitial.addClass('animated flipInX');
        randomInitial.clone().appendTo("#loaded-devs").removeClass("initial animated flipInX");


            setTimeout(this.changeDevs, 3000);
        }
    }

This works great except sometimes it selects the same div, which messes up my animation. How can I continue to select random divs, without making sure the same div doesn't repeat back-to-back?

Upvotes: 0

Views: 155

Answers (4)

jrook
jrook

Reputation: 3519

One way to store the last selected div is to add a class (or another attribute) to it. Here is a take which I think achieves the same result in a simpler way than the other answers:

changeDevs: function() {
    var divNotToFlip = $('div.lastOne');
    var candidateDivs = $('div:not(.lastOne)');
    var divToFlip = candidateDivs.eq(Math.floor(Math.random()*candidateDivs.length));
    divToFlip.addClass('animated flipInX lastOne');
    divNotToFlip.removeClass('lastOne animated flipInX');  //Return the last selected div to the pool
}

Note: I also removed the setTimeout function in changeDevs function. Using this method, there is no need for new fields in DevRotator object just to hold the last selected element.

Working fiddle

Upvotes: 1

Himanshu
Himanshu

Reputation: 490

Stored the current value as lastItem, then generates new Random Value for devToFlip untill devToFlip ! = lastItem. After coming out of while loop, saves the newly generated devToFlip as lastItem.

var DevRotator = {
  initialDev: '.featured-dev.initial',
  notInitial: '#loaded-devs .featured-dev',
  lastItem: null,
  devToFlip: null,
  init: function() {
    setInterval(this.changeDevs.bind(this), 100);
  },
  changeDevs: function() {
    this.lastItem = this.devToFlip;
    while (this.devToFlip == this.lastItem) {
      this.devToFlip = Math.floor(Math.random() * $(this.initialDev).length);
    }
    this.lastItem = this.devToFlip;
    $(this.initialDev).removeClass('animated flipInX');
    var randomInitial = $(this.initialDev).eq(this.devToFlip);
    randomInitial.addClass('animated flipInX');
    randomInitial.clone().appendTo("#loaded-devs").removeClass("initial animated flipInX");
  }
};

DevRotator.init();
.animated {
  background-color: red;
}

div {
  background-color: yellow;
  margin: 5px;
  height: 50px;
  width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>
<div class="loaded-dev featured-dev initial">
</div>

Upvotes: 0

HoofHarted
HoofHarted

Reputation: 176

I was able to save the last found item in a variable, then the next time it gets a div, filters out that div from the list of divs, then selects a random div from the result of that.

This is the main part of it

// get a random index that's 1 less than the length of the initDev
// array because we'll be removing an item

var randomInitial = Math.floor(Math.random() * ($(this.initialDev).length - 1));

// get an array that does not include the one we previously used
// and select the item at randomInital
this.lastDiv = $(this.initialDev).filter(function() { return this != self.lastDiv; })[randomInitial];

See this working fiddle for an example.

Upvotes: 0

Paflow
Paflow

Reputation: 2347

Just store the last selected div...

 lastDiv: -1;
 changeDevs: function() {
     var devToFlip = 1; 
     while (devToFlip == this.lastDiv)
          {devToFlip = [Math.floor(Math.random()*$(this.notInitial).length))]};

Upvotes: 0

Related Questions