Reputation: 2101
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
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.
Upvotes: 1
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
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
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