I have three divs with the attribute row. When the page loads I want to randomly select one of the divs and apply the class .show. From here, when the document is clicked I want one of the divs out of the remaining two divs to be randomly selected and have the class .show applied to it. When the document is clicked again, the last remaining div showed have .show applied to it. Now all three divs have the class .show. If the document is clicked again visual cycle should be restart so that only one randomly selected div has the class .show.
I've laid out (as a javascript novice) my approach but I don't know how to keep track of the rowArray which records which divs are remaining (the divs that DONT have the class .show) at each stage of the counter.
Any pointers in the right direction would be greatly appreciated. I have attached a JSFiddle with comments.
var selector = Math.floor((Math.random() * 3));
var rowArray = [0, 1, 2];
var counter = 0;
$(document).ready(function() {
counter++
$('#cnt').find("div[row=" + selector +"]").addClass('show');
var newrowArray = rowArray.splice(selector, 1);
$(document).on("click", function() {
counter++
if (counter ==1 ) {
} else if (counter == 2) {
} else {
counter = 1;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cnt">
<div row="0"></div>
<div row="1"></div>
<div row="2"></div>
</div>
you can make a function that selects all the elements that do not have show class, using this list select a randomIndex and then randomly add class show to one these elements. You can all this function on page load and from click on document.
$(document).ready(function() {
function selectDiv(){
var notSelectedDivs = $("div[row]:not(.show)");
if(!notSelectedDivs.length){
$('.show').removeClass('show');
notSelectedDivs = $("div[row]:not(.show)");
}
var randomIndex = Math.floor((Math.random() * notSelectedDivs.length));
$(notSelectedDivs[randomIndex]).addClass('show');
}
$(document).on("click", function() {
selectDiv();
});
selectDiv();
});
.show{
color: #ff0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cnt">
<div row="0">1</div>
<div row="1">2</div>
<div row="2">3</div>
</div>
Related
I am trying to create somewhat of a tabSelect function in a card game where the player will be able to select 1 of the 5 cards in their hand. I made a highlight class and am adding it to a div containing the card image so the outline changes from blue to light blue. So in the loop the class should be added to the first div, then the second div while removing it from the first div, then the third div while removing it from the second div....etc.
this is what i have tried so far but its not working as intended :
selectCard() {
const $playerOneHand = $('.pOne')
for (i = 0; i < $playerOneHand.length; i++) {
if ($($playerOneHand[i - 1]).hasClass('highlight') == true) {
$($playerOneHand[i - 1]).removeClass('highlight')
}
if ($($playerOneHand[i]).hasClass('highlight') == false) {
$($playerOneHand[i]).addClass('highlight')
return
}
}
}
Get the index of the card that's currently highlighted. Increment that index to get the one to highlight in its place.
function selectCard() {
var index = $(".pOne.highlight").index(".pOne");
index = (index + 1) % $(".pOne").length; // increment and wrap around
$(".pOne").removeClass("highlight");
$(".pOne").eq(index).addClass("highlight");
}
$("#next").click(selectCard);
.pOne {
height: 30px;
width: 30px;
background-color: yellow;
}
.pOne.highlight {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="pOne highlight">1</div>
<div class="pOne">2</div>
<div class="pOne">3</div>
<div class="pOne">4</div>
<div class="pOne">5</div>
<button id="next">Next Card</button>
I would like to shuffle specific DIVs (based on class) around on each page load.
Note i'm using a Wordpress Theme and as such, do not have full control over HTML structure without changing base themes (which i'm not willing to do)
jfiddle is here.
$(function() {
$(".shuffle").each(function() {
var parent = $(this),
divs = parent.children().remove();
while (divs.length) {
parent.append(divs.splice(Math.floor(Math.random() * divs.length), 1)[0]);
}
});
});
Parent DIV class = "shuffle"
Child DIVs class = "shuffle-child"
What am I doing wrong? Apologies for lack of JS experience!!
For your particular scenario you can use the following, adapted for jQuery from https://stackoverflow.com/a/11972692/2413733 #AlexeyLebedev's answer using the Fischer-Yates Shuffle.
var shuffleKids = $('.shuffle-kids'), // the elements to shuffle
shuffle = shuffleKids.parent(); // the container div
for (var i = shuffleKids.length; i >= 0; i--) {
shuffle.append(shuffle.children()[Math.random() * i | 0]);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='shuffle'>
<div class='shuffle-kids'>milk</div>
<div class='shuffle-kids'>butter</div>
<div class='shuffle-kids'>eggs</div>
<div class='shuffle-kids'>orange juice</div>
<div class='shuffle-kids'>bananas</div>
</div>
I'm creating portfolio section where every portfolio item shows as an image and every portfolio item has its own div which is hidden and contains more information about that item. When the user clicks on some portfolio item (image) div with more information for that item is shown. Each div with more info has two classes, portf-[nid] and portf ([nid] is Node ID, I work in Drupal and this class with [nid] helps me to target portfolio item with more info div for that item).
Each of the more info divs contains arrows for item listing (next and previous) and I need to get them function, so when the user clicks on previous I need to hide current and show the previous item if it exists(when clicks on next to hide current and show next item if it exists).
My markup looks like:
<div class="portf-3 portf">
//some elements
</div>
<div class="portf-6 portf">
//some elements
</div>
<div class="portf-7 portf">
//some elements
</div>
My question is how to hide the div I'm currently on and show the previous (or next). For example: if it is currently shown div with class portf-6 and user clicks on previous arrow, this div is being hidden and div with class portf-3 is being shown.
It's not the problem to hide/show the div but how to check if there is the div above/below the current div and to target that div above or below the current div?
Here you are:
function GoToPrev()
{
var isTheLast = $('.portf:visible').prev('.portf').length === 0;
if(!isTheLast)
{
$('.portf:visible').hide().prev().show();
}
}
function GoToNext()
{
var isTheLast = $('.portf:visible').next('.portf').length === 0;
if(!isTheLast)
{
$('.portf:visible').hide().next().show();
}
}
To check if prev / next element is present or not, you can make use of .length property as shown below
if($('.portf:visible').prev('.portf').length > 0) // greater than 0 means present else not
same for next element
if($('.portf:visible').next('.portf').length > 0)
As you also need to update the next and previous buttons, I would suggest a more structured approach to the whole thing:
function update(delta) {
var $portfs = $('.portf');
var $current = $portfs.filter(':visible');
var index = $portfs.index($current) + delta;
if (index < 0) {
index = 0;
}
if (index > $portfs.length){
index = $portfs.length;
}
$current.hide();
$portfs.eq(index).show();
$('#prev').toggle(index > 0);
$('#next').toggle(index < $portfs.length-1);
}
$('#prev').click(function () {
update(-1);
});
$('#next').click(function () {
update(1);
});
// Hide all initially
$('.portf').hide();
// Show the first with appropriate logic
update(1);
JSFiddle: http://jsfiddle.net/TrueBlueAussie/xp0peoxw/
This uses a common function that takes a delta direction value and makes the decisions on range capping an when to hide/show the next/previous buttons.
The code can be shortened further, but I was aiming for readability of the logic.
If the next/prev buttons are correctly shown the range checking is not needed, so it simplifies to:
function update(delta) {
var $portfs = $('.portf');
var $current = $portfs.filter(':visible');
var index = $portfs.index($current) + delta;
$current.hide();
$portfs.eq(index).show();
$('#prev').toggle(index > 0);
$('#next').toggle(index < $portfs.length-1);
}
JSFiddle: http://jsfiddle.net/TrueBlueAussie/xp0peoxw/1/
I have a div with class 'bannergroup' that contains multiple divs 'banneritem'. I want these items to rotate (fade in then fade out) in place of each other.
I can have several divs with the class bannergroup and each one should rotate separately.
Here is the HTML:
<div class="bannergroup">
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
</div>
<div class="bannergroup">
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
</div>
My Jquery looks like:
$('.banneritem').css('display', 'none');
$('.bannergroup').children('.banneritem').each(function( i ) {
$(this).fadeIn().delay(4000).fadeOut();
});
The problem: the each statement continues to run before the previous div completes. I want it to wait until the previous child is gone. Also, I need this to continuously run. After a single time it stops. I can put this into a function, but I am not sure how to know to call it again.
EDIT: There are not always 4 child items. Also one group may have a different number of children than the others, but they should both rotate in-sync. It is ok if one completes before the other and then just restarts itself.
I have answered this question multiple times before. This time I will try wrapping it in a jQuery plugin. The .rotate() function will apply the effect you want to the children of the matched elements, a fade in/out effect per children in a continuous animation.
$.fn.rotate = function(){
return this.each(function() {
/* Cache element's children */
var $children = $(this).children();
/* Current element to display */
var position = -1;
/* IIFE */
!function loop() {
/* Get next element's position.
* Restarting from first children after the last one.
*/
position = (position + 1) % $children.length;
/* Fade element */
$children.eq(position).fadeIn(1000).delay(1000).fadeOut(1000, loop);
}();
});
};
Usage:
$(function(){
$(".banneritem").hide();
$(".bannergroup").rotate();
});
See it here.
jsFiddle example
$('div.bannergroup').each(function () {
$('div.banneritem', this).not(':first').hide();
var thisDiv = this;
setInterval(function () {
var idx = $('div.banneritem', thisDiv).index($('div.banneritem', thisDiv).filter(':visible'));
$('div.banneritem:eq(' + idx + ')', thisDiv).fadeOut(function () {
idx++;
if (idx == ($('div.banneritem', thisDiv).length)) idx = 0;
$('div.banneritem', thisDiv).eq(idx).fadeIn();
});
}, 2000);
});
You can solve this problem in 2 ways. The one below is the easiest, using the index to increase the delay per item.
$('.banneritem').css('display', 'none');
$('.bannergroup').children('.banneritem').each(function( i ) {
$(this).delay(4000 * i)).fadeIn().delay(4000 * (i+1)).fadeOut();
});
I have 10 divs with class "animate" and IDs from "one" to "ten", for example:
<div class="animate" id="six">
bla bla content
</div>
I need to cycle the visibility of these ten layers in a continuous loop.
The method doesn't have to be very efficient, it just has to work OK.
I have tried running them through a for loop and fade in then fade out them one by one but they all became visible at the same time then faded out together at each iteration.
The code I used for that:
layer_ids = ['one','two','three','four','five','six','seven','eight','nine','ten'];
for(i = 0; i < 300; i++)
{
animate_id = layer_ids[i%10];
element_selector = '.animate#'+animate_id;
$(element_selector).fadeIn(1500).delay(1000).fadeOut(1500);
}
I expected that at the first iteration the first one would be shown then hidden, then the second one, etc.
How can I show then hide them in sequence?
Another thing I'd like to know is how I can run this continuously. I tried with a while(1) but the page froze.
Would rather do this without 3rd party plugins if possible.
Smoothly transitions between content.
Use the setInterval milliseconds value to decide how long you would like to display each section.
Add as many DIVs as needed to the HTML, the code will count them.
Demo: http://jsfiddle.net/wdm954/QDQhu/4/
Any specific reason you want to do this with cycle?
Think the same could be accomplished with much less code:
var els = $("div.animate").hide();
function rotate(){
for (var i=0;i<els.length;i++){
$(els[i]).delay(i*1000).fadeIn(1500).delay(1000).fadeOut(1500);
}
setTimeout(rotate, i*1000);
}
rotate();
Example on jsfiddle, and it isn't restricted to the number of elements.
Version 1, fades in the next element while the currently visible element is still fading out. This looks nice if they're positioned on top of each other.
var roller = $('.animate'),
curr = roller.length-1;
function fadeOut() {
roller.eq(curr).fadeOut(1500, fadeIn);
}
function fadeIn() {
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, fadeOut);
}
fadeOut();
http://jsfiddle.net/kaFnb/2/
Version 2, fades the next element in only once the previous element has been faded out. This works well when the content isn't positioned on top of each other (like in the fiddle example).
var roller = $('.animate'),
curr = roller.length-1;
function toggleNextRoller() {
roller.eq(curr).fadeOut(1500);
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, toggleNextRoller);
}
toggleNextRoller();
http://jsfiddle.net/kaFnb/1/
I put together a little example for you. hope it helps:
$(function () {
function animateBoxes(targetElement, delay) {
var anims = targetElement;
var numnberOfAnims = anims.size();
anims.eq(0).addClass('visible').fadeIn();
setInterval(function () {
$('.visible').fadeOut(function () {
$(this).removeClass('visible').next().addClass('visible').fadeIn();
if ($(this).index() + 1 == numnberOfAnims) {
anims.eq(0).addClass('visible').fadeIn();
}
});
}, delay);
}
animateBoxes($('.animate'), 2000);
});
Html:
<div class="animate visible">
Content 1
</div>
<div class="animate">
Content 2
</div>
<div class="animate">
Content 3
</div>
<div class="animate">
Content 4
</div>
<div class="animate">
Content 5
</div>
CSS:
.animate
{
display:none;
border:solid 1px red;
padding:30px;
width:300px;
}