having problems looping through elements using while loop - javascript

I would like to loop through a collection of divs and randomly fade them out when a click event is triggered but at the moment I have to continually click to fade the other divs all out. I would rather click a div and have all its divs randomly fade out. I have added some console.logs into the while loop and everything seems to work fine, problem is when I try to fadeout the actual elements. If anyone could help that would be great?
Fiddle here: http://jsfiddle.net/kyllle/sdpzJ/7/

I'm not sure if I understand your question, but here's a possible solution:
function randomFadeOut(i){
var random;
var e = 0;
while (e < ctnLength) {
random = Math.random() * 1000;
$(ctn[e]).not(i).delay(random).animate({ opacity : 0 });
e++;
}
}
This will fade out all the divs at random times when you click on one.
I updated your fiddle here.

Your random number generator is outside of your loop - so you only get one random number over and over.
Try this:
function randomFadeOut(i){
var random
for (var e=0;e<ctnLength;e++) {
random = Math.floor(Math.random() * ctnLength);
$(ctn[random]).not(i).animate({ opacity : 0 });
}
}
Of course, since this is random, the same cells can be selected more than once, which will leave a number of cells behind.

Decided to throw this out there, too. Simplified.
$(function() {
var $ctn = $('#container .ctn');
function randomFadeOut() {
var $r = $ctn.not($(this));
var e = 0;
while (e < $ctn.length) {
$r.eq(e).delay(Math.random() * 500).animate({ opacity: 0 });
e++;
}
}
$ctn.hide().click(randomFadeOut).each(function(v) {
$(this).delay(50 * v).fadeIn();
});
});
http://jsfiddle.net/sdpzJ/15/

Here is a better and more efficient randomFade function:
function randomFadeOut(i){
var tmp = ctn.toArray();
tmp.sort( function(){ return Math.floor( Math.random()*3 ) -1; } );
for( var i=0; i<tmp.length; ++i ){
$(tmp[i]).delay(100 * i).fadeOut();
}
}
This way, you only go once through the array
I updated your fiddle with it as well to see it in action :)

Related

Count 1-10 in 1 sec intervals and print in div class box

I've recently completed an evaluation on a jsfiddle and completed it but probably not in the way they asked. I attempted a for loop to begin with but could not get anything print initially and tested different environments. When I finally did get it to print, it would only print the last number rather the numbers 1-10. This was my solution to printing it but not listing them out. What would be your approach to listing them out? in the Div class box provided when a button is pressed to initiate it.
https://jsfiddle.net/vjoehmq6/
function change(){
function count(num) {
if(!num)
num = 1;
var x = document.getElementsByClassName("box");
x[0].innerHTML = num;
if(num < 10) {
setTimeout(function() { count(num + 1); }, 1000);
}
}
setTimeout(count, 1000);
}
If you want to append text vertically
x[0].innerHTML += '<br>'+num;

How to use jQuery event in sequence

I am trying to play around with learning jQuery and have made the following jsFiddle:
http://jsfiddle.net/jkNK3/
The idea is to have a div's color change on click. Fine, I got that but I am wondering if there is a way to have the div's color change through multiple classes changes, perhaps with some sort of array or loop. Let me explain.
I have created several CSS classes like so:
.color1 {..}
.color2 {..}
.color3 {..}
.color4 {..}
.color5 {..}
.color6 {..}
and am wondering if we can do something like
addClass("color" + i)
where i can be looped through 1 - 6.
Is there any way to accomplish this? Thanks for the help.
This is a good place to consider the danger of global javascript namespaces. Here's a simple example that takes advantage of closures to avoid that with jquery:
$(function() {
var numb = 1;
// this bit of managing the color state swap is another topic for discussion, so keeping it simple
var colors_len = 6;
$("div").click(function() {
// this closure has access to the numb variable
if (numb < colors_len) {
numb++;
$(this).addClass("color" + numb);
$(this).removeClass("color" + (numb-1));
} else {
numb = 1;
$(this).removeClass("color" + colors_len);
$(this).addClass("color" + numb);
}
});
});
http://jsfiddle.net/2taH5/
ps. Jquery ui also has a swap class method but that is more for animations
In my opinion the easiest would be to just store the color number in jQuery's handy data(), and then increment it from that:
function fnClick() {
var numb = $(this).data('color') || 2;
$(this).addClass("color" + numb).data('color', ++numb)
}
FIDDLE
To make it go back to the first color after the last color etc
function fnClick() {
var numb = $(this).data('color') || 2;
numb = numb == 7 ? 1 : numb;
$(this).removeClass().addClass("color" + numb).data('color', ++numb)
}
FIDDLE
How about using a random number to give a random color to the div.
var classCount = 6;
$(document).ready(function () {
$("div").on("click", fnClick);
});
function fnClick(e) {
// Get the currently clicked element
var $this = $(e.target),
className = 'color' + Math.floor((Math.random() * classCount )+1);
// Remove the exixting class/s
$this.removeClass();
// Add the class
$this.addClass(className);
}
Check Fiddle

Take 3 random items from a ul and append to another list with random fadeIn and fadeOut

So I have got so far with this function, but now I am struggling with one issue.
I have made a fiddle here: http://jsfiddle.net/lharby/WhUJq/3/
I have a ul which is hidden the function takes 3 li items from the ul and appends them to a visible ul.
What I want to do is to have a nice fadeIn and fadeOut function on these items. And I was hoping that the fade could be staggered over each li.
This is the function:
function rndSlider() {
var $show = 3, // Number of items to show
$elemLength = $('.slider li').length, // Total items
$firstPart = '<li><img src="/img/slider/0',
$lastPart = '.jpg" /></li>',
array = [], // array with all available numbers
rnd, value, i,
$wrapper = $('.slider-clone');
$('.slider-clone li').remove();
for (i = 0; i < $elemLength; i++) {
array[i] = i + 1;
}
for (i = 0; i < $show; i++) { // pick numbers
rnd = Math.floor(Math.random() * array.length);
value = array.splice(rnd,1)[0]; // remove the selected number from the array and get it in another variable
$wrapper.append($firstPart + value + $lastPart);
}
}
I wondered if I needed an each function on the
$('.slider-clone li').remove();
Applied to each li element (I have a fadeIn function working on the fiddle, but not the fadeOut).
And then a fade in on the
$wrapper.append($firstPart + value + $lastPart);
But I cannot seem to get anything to work, when I apply one of these, it seems to upset the main function from running.
TIA
Hmm.. well thats awkward.. When i posted this.. it worked well.. I think this issue might have to do with the fadeIn and fadeOut being done async.. The problem here is that when the child images are created the fadeOut effect-callback removes them..
$(this).children().remove();
I've updated your fiddle:
http://jsfiddle.net/WhUJq/15/
So if i understand you correctly, the problem is the fadeOut() effect?
replace:
$('.slider-clone li').each(function(){
$(this).fadeOut(400);
});
with the following code to solve that issue:
$wrapper.fadeOut('slow', function(){ $(this).children().remove(); });

How to increase the delay on animation on every pass of a for loop

First I've created a basic demonstration of what I have at the moment here.
Second this is the javascript I'm using.
var boxes = ["#one","#two","#three","#four"];
boxhover = function(a){
$("#hover").hover(
function(){
$(a).stop(true).delay(250).animate({opacity:1});
},
function(){
$(a).stop(true).delay(250).animate({opacity:0});
}
)
}
for(var i=0; i<boxes.length; i++)
{
boxhover(boxes[i])
}
What I'm hoping to achieve is to have each box hover one after the each other with a delay time of 250. I've tried adding a delay to the animation function (as you can see above) and also a setTimeout in the for loop, but no luck. Any help would be great.
You can pass in the array index as an additional parameter to your boxhover function and then perform a multiplication on the delay factor.
var boxes = ["#one","#two","#three","#four"];
boxhover = function(a, i){
$("#hover").hover(
function(){
$(a).stop(true).delay(250 * i).animate({opacity:1});
},
function(){
$(a).stop(true).delay(250 * i).animate({opacity:0});
}
)
}
for(var i=0; i<boxes.length; i++)
{
boxhover(boxes[i], i)
}
jsfiddle
Alternative Solution:
To avoid binding multiple hover event handlers on #hover and having to maintain an array of IDs, you can do the following:
$("#hover").on({
'mouseenter': function(e) {
// Animate the box set to visible
animateBoxSet(1);
},
'mouseleave': function(e) {
// Animate the box set to invisible
animateBoxSet(0);
}
});
function animateBoxSet(opacity) {
// For each box
$('.box').each(function (index, element) {
// Set the delay based on the index in the set
var delay = 250 * index;
// Animate it the visibility after the delay
$(element).stop(true).delay(delay).animate({
'opacity': opacity
});
});
}
jsfiddle

Duplicate and change a function

I have this code here:
function slideDown(){
//get the element to slide
var sliding = document.getElementById('slideDiv'+x);
//add 1px to the height each time
sliding.style.height = parseInt(sliding.style.height)+5+'px';
t=setTimeout(slideDown,15);
if (sliding.style.height == "401px"){clearTimeout(t);}
}
which gets element slideDivx and increases its height until it reaches 401px.
I have 20 of these divs (each called slideDiv1, slideDiv2, ...) and what I want is for div 10 to start, then when it has reached about 100px in height, I want 9 and 11 to start and so on so forth.
I've tried setInterval and increased x each time, but that doesn't work because it stops the previous div animating and moves on to the next one before it's finished. I think that's because I'm changing that function right?
What I'm wondering is, do I have to duplicate the function for each set of divs or can I automate that?
I have to be able to do it all in native JavaScript rather than jQuery because it's for a university project.
It sounds like you simply need to create slideDown with a parameter and then send your set of elements in an array like so:
var elementIntervals = [];
function animateElements(elementArray)
{
for(var j = 0; j < elementArray; j++)
{
(function(element, index)
{
elementIntervals[index] = setTimeout(function()
{
slideDown(element, index);
}, 15 + (100 * index));
})(elementArray[j], j);
}
}
function slideDown(sliding, index)
{
sliding.style.height = parseInt(sliding.style.height)+5+'px';
if(sliding.style.height == "401px")
clearTimeout(elementIntervals[index]);
else
elementIntervals[index] = setTimeout(function()
{
slideDown(sliding, index);
}, 15);
}

Categories