2012-06-01 3 views
0

Я получил этот документ дерево суб-дерево:Удаление элементов, а затем добавить их снова

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

То, что я пытаюсь добиться, чтобы опорожнить childNodes из #content, а затем заполнить его снова <div> с class="tile". Вот что я сделал.

$(".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); 
}); 

Кажется, что .tiles добавляют до remove() называется так, что ничего не происходит на экране ...

Кто-нибудь есть объяснение такого поведения? Похоже, что добавление таймера не является хорошим решением.

Спасибо!

+0

'tile' или' title' человек? –

+0

'tile' ты прав. Вопрос отредактирован. –

+0

Можно ли дать нам демо на [Fiddle] (http://jsfiddle.net/)? –

ответ

3

$(this).remove(); называется showTileSpeed миллисекунды после fadeOut называется. Но tiles[tileIndex]() вызывается сразу после того, как был вызван fadeOut.

Вы должны добавить плитки снова, как только все плитки будут удалены. Вы можете достичь этого, передав выбранным элементам $.when[docs] и зарегистрировав обратный вызов (с .done()[docs]) на возвращаемом обещанном объекте. Обратного вызова вызывается, когда все анимации были завершены:

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); 
    }); 
}); 

Смотрите также Execute complete function only once in jQuery animation? (особенно this answer).


Update: Так как кажется, что вызов .remove() вмешивается в тестах на состояние анимации, перемещая вызов .remove() может быть лучшим решением:

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); 
    }); 
}); 

Но если вы хотите только обновите содержимое элементов, вам не нужно удалять их из DOM.

+0

Никогда не слышала об этих функциях. Я попробую и дам вам знать, но это кажется очень многообещающим, спасибо! –

+0

Кажется, работает только, если я выбираю между 'fadeOut()' или 'remove()'. Играя свой код в моем окружении, я должен дважды щелкнуть по кнопке, чтобы она работала. Поскольку эффект затухания только для улучшения, я пойду без него. Спасибо за вашу помощь! –

+1

Mmmh. Возможно, проблема заключается в '.remove'. Он также удаляет данные jQuery из элементов и, возможно, это необходимо для определения состояния анимации. Попробуйте '$ (this) .detach()' или удалить обратный вызов 'fadeOut' и поместите' $ tiles.remove() 'внутри обратного вызова, переданного в' .done'. –

0

Я не уверен, что именно вы имеете в виду? В любом случае, взгляните на это, это то, что вам нужно?

$(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); 
     }); 
    }); 
}); 
+1

Код в обратном вызове выполняется для каждого элемента '.tile'. Я не думаю, например. 'tiles [tileIndex]()' должен выполняться (в этом случае) три раза, только один раз. –

+0

О, понял, что вы имеете в виду. –

+0

@FelixKling: вы правы и, более того, я уже пробовал это решение, но функция 'tiles []()', казалось, работала до 'remove()' –

Смежные вопросы