Boris Delormas
Boris Delormas

Reputation: 2549

Removing elements and then adding them again

I've got this document tree sub-tree:

<div id="content">
    <div class="tile"></div>
    <div class="tile"></div>
    <div class="tile"></div>
</div>

What I'm trying to achieve is to empty the childNodes of #content, and then populate it again with <div>s having the class="tile". Here is what I've done.

$(".tile").fadeOut( showTileSpeed, function() {
    $(this).remove();
});


tiles[tileIndex]();// function adding .tiles to my #content

$(".tile").first().fadeIn(showTileSpeed, function showNext() {
    $(this).next(".tile").fadeIn(showTileSpeed, showNext);
});

It seems that the .tiles are added before the remove() is called so that nothing happens on screen...

Does anyone have an explanation for this behavior? It appears that adding a timer is not a good solution.

Thanks!

Upvotes: 0

Views: 230

Answers (2)

Felix Kling
Felix Kling

Reputation: 816334

$(this).remove(); is called showTileSpeed milliseconds after fadeOut was called. But tiles[tileIndex]() is called immediately after fadeOut was called.

You should add the tiles again once all the tiles have been removed. You can achieve this by passing the selected elements to $.when [docs] and register a callback (with .done() [docs]) on the returned promised object. The callback gets called once all animations have been completed:

var $tiles = $(".tile").fadeOut(showTileSpeed, function() {
    $(this).remove();
});

$.when($tiles).done(function() {      // <-- after all animations do this
    tiles[tileIndex]();

    $(".tile").first().fadeIn(showTileSpeed, function showNext() {
        $(this).next(".tile").fadeIn(showTileSpeed, showNext);
    });
});

See also Execute complete function only once in jQuery animation? (especially this answer).


Update: Since it seems that calling .remove() interferes with the tests for the animation state, moving the call to .remove() might be a better solution:

var $tiles = $(".tile").fadeOut(showTileSpeed);

$.when($tiles).done(function() {
    $tiles.remove();
    tiles[tileIndex]();

    $(".tile").first().fadeIn(showTileSpeed, function showNext() {
        $(this).next(".tile").fadeIn(showTileSpeed, showNext);
    });
});

But if you only want to update the content of the elements, you don't have to remove them from the DOM.

Upvotes: 3

Tooraj Jam
Tooraj Jam

Reputation: 1612

I'm not sure what exactly you mean? Anyway, take look at this, is this what you need?

$(document).ready(function() {
    $(".tile").fadeOut( showTileSpeed, function() {
        $(this).remove();
        tiles[tileIndex]();// function adding .tiles to my #content
        $(".tile").first().fadeIn(showTileSpeed, function showNext() {
            $(this).next(".tile").fadeIn(showTileSpeed, showNext);
        });
    });
});

Upvotes: 0

Related Questions