Cycle visibility for layers - javascript

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;
}

Related

Loop through multiple of same blocks of markup in JS and perform same function without interference

I am looking to to fade in / out text labels, where only one label shows at a time in a given block. The markup is like this:
<div class="subtitles">
<h3 class="subtitle" data-order="0">
label 1
</h3>
<h3 class="subtitle" data-order="1">
label 2
</h3>
<h3 class="subtitle" data-order="3">
label 3
</h3>
</div>
[repeat block nth number of times]
I can loop through one set fine with this javascript:
var divs = $('.subtitles').find('h3.subtitle');
divs.hide();
i = 0;
// fade h3s in / out
(function cycle() {
divs.eq(i).fadeIn(400)
.delay(1000)
.fadeOut(400, cycle);
i = ++i % 3;
})();
But more than one block on the page and things get tangled. How can I loop over multiple blocks and apply the same behaviour?
You need to encapsulate the desired behaviour in a function, so that each set of cycling elements gets its own offset.
function cycle($els) {
var i = 0;
$els.hide();
(function loop() {
$els.eq(i++).fadeIn(400)
.delay(1000)
.fadeOut(400, loop);
i %= $els.length;
})();
}
and then you can use .each to start each group of subtitles cycling around independently:
$('.subtitles').each(function() {
cycle($(this).find('h3.subtitle'));
});
Try .each()
Code:
$('.subtitles').each(function() {$(this).find('h3.subtitle');$(this).hide()});
Edit: According to question OP, the i variable is getting variabletangled, and the reason is due to javascript Hoisting. Please read this link, to understand what is happening to the

Text showing in a sequence

I am trying to run a simple sequence with text. I want the text to show for a second and then hide() or fadeOut(), then the next() one within the queue to show.
Does anyone see what I am doing wrong? Right now, only the last div is showing.
Side note, can anyone point me to a function or give me an idea of how to make the text slide in from the right, like on this page. https://artversion.com/
$(function() {
$('.cover1-seq').delay(1000).queue(function(next) {
$(this).show().prev().hide();
next();
})
/*.toggle("slide", {
direction: 'right'
}, 1000);*/
});
.cover1-seq {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="cover1-seq">
<h1 class="cover1-title">Apple</h1>
</div>
<div class="cover1-seq">
<h1 class="cover1-title">Book</h1>
</div>
<div class="cover1-seq">
<h1 class="cover1-title">Cat</h1>
</div>
The javascript is executing all at once, in the case 3 times the '$(this).delay(1000)', what will happen is that it will execute everything together.
I made an adjustment in your code to run every 1 second:
$(function() {
var i = 0;
$(".cover1-seq").each(function(){
$(this).delay(1000 * ++i).queue(function() {
$(this).show().prev().hide();
});
});
});
Or, as asked, so it keeps repeating. And to execute when the page loads, we add the '$(document).ready':
$(document).ready(function() {
var arr = $(".cover1-seq");
var arrLen = arr.length;
var i = 0;
setInterval(function(){
$(".cover1-seq").hide();
$(arr[i]).show();
i === arrLen ? i = 0 : i++;
}, 1000);
});
I hope I have helped!

Choose a random div and apply css class with timeout and loop this?

I have the following HTML structure:
<div class="change me">Item 1</div>
<div class="change me">Item 2</div>
<div class="change me">Item 3</div>
<div class="change me">Item 4</div>
<div class="change me">Item 5</div>
<div class="change me">Item 6</div>
And CSS:
body {
font-family: Helvetica, Arial, sans-serif;
font-size:20px;
}
div {
background-color: #fff;
display: block;
border-bottom: 1px solid #ccc;
background-image: url(http://cdn.sstatic.net/Img/mini-hero-bg.png?v=7f269bbbdb22);
}
.change {
background-image: none;
}
Now I would like to pic a random div with Javascript / jQuery and "remove" the class "change" so that the default background image of the specific div will be visible. My code looks like that atm:
var divs = $(".me").toArray();
var divlength = divs.length;
setInterval(function(){
var randomnum = Math.floor(Math.random()*divlength);
var randomdiv = divs[randomnum];
$(randomdiv).addTemporaryClass("change", 1000);
}, 1000);
$.fn.extend({
addTemporaryClass: function(className, duration) {
var elements = this;
setTimeout(function() {
elements.addClass(className);
}, duration);
return this.each(function() {
$(this).removeClass(className);
});
}
});
I need to improve this to achieve the following:
I would like to have a smoother change from no-background-image to the visibility of the default background-image. Some fading effect or something like that. Already tried to add some transition to the div CSS but with no success.
Sometimes there is no "change"-class removing and for some time no background-image of any div visible but I need at least one image being visible everytime
I need to start the "remove"-class-thing immediately on page load so that there is already one background-image of a random div visible
Here is the current fiddle: http://jsfiddle.net/uRd6N/500/
Thx for your help, I am a noobie and not really familiar with JS / jQuery. If you know a better way to do this whole thing you could tell me too.
Regards
I have taken a look, and updated your Fiddle at http://jsfiddle.net/uRd6N/513/
Some changes I made:
var randomnum = Math.floor(Math.random()*(divlength-1));
Remember, array indexes start at 0, not 1, therefore I made the random number decrement by 1, otherwise your last div in the array would never have been reached.
var divs = $(".me").toArray();
var divlength = divs.length;
I declared these two variables outside of the scope of the setInterval function, to optimize the code a little more.
clearTimeout(doChange);
var doChange = setTimeout(function() {
elements.addClass(className);
}, duration);
I assigned the setTimeout to a variable and cleared it upon each call of the function, to avoid bubbling.
I am still looking into the transition, however another issue I spot is that there is no control mechanism to make sure that the last selected random number does no occur again on the next pick. This will need to be controlled.
Update 1
I have added random first div with background image on load, and removed it with first interval.
Update 2 (Duplicate Random Number Control)
Alright, I have managed to piece together some very simply logic that checks if the chosen random number is a re occurrence of the last chose number, and it decrements or increments the random number by 1, but ALWAYS within the scope of the div count, so it's safe. It's nothing smart, or complex, just simple procedural code. I added console logs, open your console and take a look at it in action. Code is as follows:
console.log("Chosen number is "+randomnum);
if(randomnum == lastnum){
console.log("We have a duplicate ("+randomnum+")");
if( (randomnum-1) >= 0 ){
randomnum = (randomnum-1);
console.log("Duplicate solved, it is now "+randomnum);
}else if( (randomnum+1) <= (divlength) ){
randomnum = (randomnum+1);
console.log("Duplicate solved, it is now "+randomnum);
}
}
lastnum = randomnum;
See the final udpated fiddle at this url: http://jsfiddle.net/uRd6N/537/
Happy coding!

How to loop animation in jQuery

I´m trying to loop this animation but I don´t know why it does not work ?
I have 4 divs with differences images and I want to loop this to replay again and again.
$(document).ready(function () {
setInterval("comeon()", 2000);
});
function comeon() {
var current = $(".current");
var next = current.next();
if (next.length == 0) {
next = $(".current:first");
}
current.removeClass('current').addClass('previous');
next.css("opacity", "0.0").addClass("current").animate({
opacity: 1.0
}, 500, function () {
current.removeClass("previous");
comeon();
});
What I have done wrong ?
**UPDATE**
<div id="slider">
<div class="current" style="background-color:#F00;position:absolute; width:400px; height:400px;"></div>
<div style="background-color:#00F;position:absolute; width:400px; height:400px;"></div>
<div style="background-color:#0F0;position:absolute; width:400px; height:400px;"></div>
<div style="background-color:#FF3;position:absolute; width:400px; height:400px;"></div>
</div><!-- End slider-->
Please have a look at http://jsfiddle.net/7kt9z/6/
next = $("cur:first");
This is attempting to select an element like <cur>. Oops!
You want:
next = $(".current:first");
or
next = cur.first();
Edit
I finally understand what you need:
next = current.siblings().first();
setInterval needs to be used in a certain way.
You need to assign setInterval to a variable, and this assignment should be attached to an event.
var setIt;
$(window).load(function() {
setIt = setInterval(comeOn, 1000);
});
Since you're using images, you can wait for all the images to load and then starting your slider (that's using the load event to assign setInterval to the variable setIt).
Also, do not wrap your function in qoutes in setInterval. Instead of:
setInterval("comeOn()", 1000)
Do this:
setInterval(comeOn, 1000)
I've got a working example here:
http://codepen.io/anon/pen/rHzpL

How to continuously rotate children in a jQuery animation?

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();
});

Categories