I am not good at jQuery so I am not sure if my assumptions are corrent.
I am using the isotope plugin, with which I want to insert elements one by one (and not everything at once) with a slight delay so it will also look like it (for the human eye)
to insert an item with isotope I use
$('#container').isotope( 'insert', $item);
so in order to insert one-by-one I am doing
$("#items_are_here").find('.item').each(function( index ) {
setTimeout(function() {
$('#container').isotope( 'insert', $(this));
},3000);
});
This however seems that the browser waits for something, and then 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 over-complicating it?
here is fiddle. In it, there are 2 buttosn - insert all - which finds all .item
and inserts them. And insert one-by-one which does the proposed way with delay. As you can see, there is no delay.
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 tested.
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);
Because .each()
runs pretty instantaneous for each entry, you'll end up with a bunch of timeouts which are more or less the same. So after about 3 seconds, all timeouts expire and the items are added.
To prevent this, you'll to make the timeout dependent on the index of the item. So item 0 will be inserted after 3 seconds, item 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));
});
$("#items_are_here").find('.item').each(function( index ) {
setTimeout(function() {
$('#container').isotope( 'insert', $(this));
},3000);
});
in the above context, $(this)
is the window
object, because it's inside setTimeout
.
Modify your code to and try:
$("#items_are_here").find('.item').each(function( index ) {
var item = $(this);
setTimeout(function(index) {
$("#container").isotope( 'insert', $(this))
},index*3000);
});
$("#items_are_here").find('.item').each(function( index ) {
var item = $(this);
setTimeout(function(i) {
$('#container').isotope( 'insert', i );
},3000);
});
little late but my workaround was:
hardcode a class to item like to_animate
the 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;
}
the snipped 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);
});
});`