92

I'm grabbing an array of jQuery objects and then via .each() modifying each individual jquery with in the array.

In this case I'm updated the class names to trigger a -webkit-transition-property to utilize a css transition.

I'd like there to be a pause before each css transition begins. I'm using the following, but there is no delay in between each update. Instead, they all appear to be updating at once.

function positionCards() {
  $cards = $('#gameboard .card');
  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, 500 )
  });
}

function addPositioningClasses($card){
  $card
    .addClass('position')
}

I was hoping setTimeout would solve this, but it doesn't seem to be working. Is there a way to accomplish the pause before each CLASS name update of each object?

2
  • try using quotes around the addPositioningClass function, like this: setTimeout( 'addPositioningClass($(this))', 500 ) Commented Mar 5, 2011 at 7:38
  • 1
    could you increment the timeout for each iteration say 500,1000,1500... Commented Mar 5, 2011 at 7:42

9 Answers 9

109

I added this as a comment but now that I have read it correctly and answered my own question this would probably work:

function positionCards() {
  var $cards = $('#gameboard .card');

  var time = 500;

  $cards.each(function() {
      setTimeout( function(){ addPositioningClass($(this)); }, time);
      time += 500;
  });
}
    
Sign up to request clarification or add additional context in comments.

10 Comments

How is your code any different than the OP? There is a scope error because addPositioningClasses doesn't exist in the context of setTimeout
I just tried it in a fiddle and it doesn't work. I may be mistaken, but I can't see how that code can work at all.
@JohnP - @DA said --> "I'm using the following, but there is no delay in between each update. Instead, they all appear to be updating at once."
Solution: which is also present in this Git: gist.github.com/Zackio/7648481
When I try, $(this) is the window. Within my each() function, it is the element but inside of the setTimeout, it is the window. I cannot seem to pass the element to the setTimeout's function!
|
54

Sorry for digging up an old thread, but this tip could be useful for similar issues:

$cards.each(function(index) {
    $(this).delay(500*index).addClass('position');
});

3 Comments

Beware that delay is meant only for the animation queue and wont work on e.g. css() (see here)
You have to use .queue() (and .dequeue()) when delaying .addClass(): $(this).delay(500*index).queue(function() { $(this).children('.flipcontainer').addClass('visible').dequeue(); });
@aksu You should copy what you have there and make it into an answer, because it's lost amongst the comments and your answer helped me make it work properly.
11

If you make a method that calls itself every 500 ms that should do that trick. The following code should work.

var __OBJECTS = [];

$('#gameboard .card').each(function() {
    __OBJECTS.push($(this));
});

addPositioningClasses();

function addPositioningClasses() {
    var $card = __OBJECTS.pop();
    $card.addClass('position');
    if (__OBJECTS.length) {
        setTimeout(addPositioningClasses, 500)
    }
}

Tested on fiddle : http://jsfiddle.net/jomanlk/haGfU/

1 Comment

I need to investigate .push() some more. I wasn't aware of that!
3

How about .delay() ?

or

function addPositioningClasses($card){
  setTimeout(function() { $card.addClass('position')}, 1000);
}

2 Comments

I always wonder that too, but to this day I haven't found a context where this method can be applied.
From what I can tell, delay() only applies to jQuery animations.
1

If you're only targeting Safari/iOS, depending on how important it is to you to control the exact timing of animation sequences, you should maybe avoid any solution that involves JS timeouts. There is no guarantee that the animation will complete at the same time as the timeout delay, particularly on slow processors or machines that have lots of stuff going on in the background. Later versions of webkit (including mobile safari) do allow for timed animation sequences via @-webkit-keyframes. Webkit.org has a nice intro to it. It's actually pretty easy to implement.

1 Comment

I am, indeed, only targetting iOS (it's an app). I'm not timing the animation sequence, but, rather, timing how long to wait until to update the class name, which then, in turn, triggers a webkit transition css.
1

Give this a try:

function positionCards() {
  $('#gameboard .card').each(function() {
      $(this).delay(500).addClass('position');
  });
}

I'll be honest... I've had $(this).delay() misbehave in the past in certain instances and work flawlessly in others. However, this was normally in conjunction with jQuery animation calls, not DOM attribute manipulation.

Please be aware .delay() does not function in the same way as setTimeout. For more information, see the jQuery .delay() documentation.

As far as I am aware, $().each does execute procedurally so the next iteration of the call should only begin after the preceding has completed.

1 Comment

I may be wrong, but in reading the jquery documentation, it look slike delay is only for delaying jQuery animations. I think you are also correct in that last paragraph. The thing was that I wasn't delaying the function call that set the class, but rather I was delaying when the class would be set. So, it applied the delay to all 30 elements at the same time, and they all then delayed the same amount of time.
0

Check this out, worked well for me! :)

jQuery('.optiresultsul li').each(function(index) {
    jQuery(this).delay(500*index).animate({ opacity: 1 }, 500,function(){
        jQuery(this).addClass('bgchecked');
    });
});

Comments

0

I struggled getting the other solutions to work. This worked for me:

function positionCards() {
  var $Element = $('#gameboard .card');
  var NumberOfElements = $Element.length;
  var Dwell = 1000;
  for (var i = 0; i < NumberOfElements; i++)
    (function(i) {
      setTimeout(function() {
        $Element.eq(i).addClass('position')
      }, Dwell * i)
    })(i);
}

Comments

-2

This code will add set the inital delay to 50ms. Then for each loop through the ".row" class it will add an additional 200ms delay. This will create a nice delayed show effect for each row.

$( document ).ready(function() {
    // set inital delay
    var dtotal = 50;
    $(".row").each(function() {
    //add delay to function
      $(this).delay(dtotal).show();
    //add 200ms to delay for each loop
      dtotal = dtotal + 200;
    });
});

1 Comment

It's best if you add some commentary and not just toss code out there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.