Loop with .each with delay in jQuery

I am not very good at jQuery, so I'm not sure if my assumptions are root.

I use an isotope plugin with which I want to insert elements one after the other (and not all at once) with a slight delay so that it also looks like (for the human eye)

to insert the isotope element that I use

$('#container').isotope( 'insert', $item); 

so in order to insert one by one, I do

 $("#items_are_here").find('.item').each(function( index ) { setTimeout(function() { $('#container').isotope( 'insert', $(this)); },3000); }); 

However, it looks like the browser is waiting for something, and then it displays them all at once

If i do

  setTimeout(function() { $("#items_are_here").find('.item').each(function( index ) { $('#container').isotope( 'insert', $(this)); }); },3000); 

everything works, but not one by one.

Is this the right way to do this? or am I complicating this too much?

here is fiddle . It has 2 buttosn - insert all - which finds all .item and inserts them. And insert one by one, which does the proposed method with a delay. As you can see, there is no delay.

+1
source share
5 answers
  var $items=$("#items_are_here").find('.item'); var i=-1; var delayed=setinterval(function() { if (++i<$items.length) $('#container').isotope( 'insert', $items.eq(i)); else clearInterval(delayed); },3000); 

not verified. or

  var $container=$('#container'); $.fn.extend({ onebyone :function ($ctnr,i) { if (!i) i = 0; var $o=$(this); setTimeOut(function() { $ctnr.isotope( 'insert', $o.eq(i)); if (++i<$o.length) $o.onebyone(i); },3000); return this; } $("#items_are_here").find('.item').onebyone($container); 
+1
source

Since .each() works pretty instantly for each entry, you get a bunch of timeouts that are more or less the same. This way, after about 3 seconds, all timeouts expire and items are added.

To prevent this, you must make the timeout dependent on the index of the element. Thus, element 0 will be inserted after 3 seconds, element 1 will be inserted after 6 seconds, etc.

 $("#items_are_here").find('.item').each(function( index ) { var item = $(this); setTimeout(function() { $('#container').isotope('insert', item); },3000 * (index + 1)); }); 
+2
source
 $("#items_are_here").find('.item').each(function( index ) { setTimeout(function() { $('#container').isotope( 'insert', $(this)); },3000); }); 

in the context above, $(this) is a window object because it is inside setTimeout .

Change your code and try:

 $("#items_are_here").find('.item').each(function( index ) { var item = $(this); setTimeout(function(index) { $("#container").isotope( 'insert', $(this)) },index*3000); }); 
+1
source
 $("#items_are_here").find('.item').each(function( index ) { var item = $(this); setTimeout(function(i) { $('#container').isotope( 'insert', i ); },3000); }); 
0
source

a bit late, but my workaround was: hardcode class for an element like to_animate

css:

.item.to_animate { opacity:0; display:block; } @keyframes TransitionClass{ 0% { opacity: 0;transform: scale(1.2); } 100% { opacity: 1;transform: scale(1); } } .animatefinish.TransitionClass{ animation-name: umScaleIn; animation-timing-function: cubic-bezier(0.19,1,.22,1); } .animatefinish.TransitionClass{ animation-duration: .8s; }

cut off for isotope

  `$('#container').isotope( 'appended', $(el) ).after(function() { $('.item.to_animate').each(function(i) { var el = $(this); setTimeout(function() { el.addClass('TransitionClass animatefinish'); el.removeClass('to_animate') }, i * 200); }); });` 
0
source

Source: https://habr.com/ru/post/951470/


All Articles