jQuery / Fazer elementos aparecerem em ordem
.delay(index * gap).fadeIn(duration) escalona os inícios. Se a duração supera o intervalo, os efeitos se sobrepõem. Para esperar a conclusão completa, inicie o próximo elemento pelo callback de conclusão anterior.
Intervalo de início e ordem de conclusão
.delay() espera na fila de cada elemento, não em uma fila compartilhada. Mesmo atraso começa aproximadamente junto; index cria escalonamento. Não bloqueia todo JavaScript.
Intervalo 200ms e .fadeIn() 400ms permitem Beta iniciar antes de Alpha terminar. Em série espera a conclusão e mais 200ms. São metas de agendamento, não tempos exatos garantidos.
.each() segue a coleção, aqui Alpha, Beta e Gamma diretos de #items. Ordenação e CSS podem diferir da leitura visual; defina a ordem apropriada.
Exemplo completo de comparação
Salve UTF-8 appearance-demo.html e abra. A Internet carrega a versão completa oficial 4.0.0. Efeitos temporizados precisam de effects, não Slim. Não precisa de servidor nem pacotes. Ordem, reinício e repetição foram conferidos no Edge para Windows com 3.7.1 e 4.0.0.
HTML começa visível e o script pronto oculta. Falha de carregamento não deixa conteúdo oculto permanentemente por CSS. A saída vem após inicialização.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Staggered versus strictly sequential appearance</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 20px; }
button, select { font: inherit; margin: 4px; }
.item { border: 2px solid teal; padding: 12px; margin: 12px 0; background: #e7f5f1; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<label>Mode <select id="mode"><option value="stagger">Staggered starts</option><option value="serial">Wait for completion</option></select></label>
<button type="button" id="start">Start</button>
<button type="button" id="reset">Reset</button>
<div id="items"><div class="item" id="alpha">Alpha</div><div class="item" id="beta">Beta</div><div class="item" id="gamma">Gamma</div></div>
<pre id="result" aria-live="polite"></pre>
<pre id="events"></pre>
<script>
jQuery(function ($) {
const $items = $("#items > .item"), gap = 200, duration = 400;
let generation = 0, busy = false, state = "ready", completed = [], events = [];
function report() {
$("#result").text(`mode=${$("#mode").val()}\nstate=${state}\nvisible=${$items.filter(":visible").length}/${$items.length}\ncompleted=${completed.join(",") || "(none)"}`);
$("#events").text(events.join("\n") || "(none)");
}
function reset() {
generation++; // Invalidate callbacks before settling old effects.
$items.stop(true, true).hide();
busy = false; state = "ready"; completed = []; events = [];
$("#start").prop("disabled", false); report();
}
function start() {
if (busy) return;
reset(); busy = true; state = "running"; $("#start").prop("disabled", true);
const run = generation, mode = $("#mode").val();
const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reduce) {
$items.show(); completed = $items.map(function () { return this.id; }).get();
events = ["Reduced motion: shown immediately"];
busy = false; state = "done"; $("#start").prop("disabled", false); report(); return;
}
function reveal(index, wait) {
const $item = $items.eq(index), id = $item[0].id;
$item.delay(wait).queue(function (next) {
if (run !== generation) return;
events.push("start " + id); next(); report();
}).fadeIn(duration, function () {
if (run !== generation) return;
completed.push(id); events.push("done " + id);
if (completed.length === $items.length) {
busy = false; state = "done"; $("#start").prop("disabled", false);
} else if (mode === "serial") reveal(index + 1, gap);
report();
});
}
if (!$items.length) { busy = false; state = "done"; $("#start").prop("disabled", false); report(); return; }
if (mode === "stagger") $items.each(function (index) { reveal(index, index * gap); });
else reveal(0, 0);
report();
}
$("#start").on("click", start);
$("#reset").on("click", reset);
$("#mode").on("change", reset);
reset();
});
</script>
</body>
</html>
Inicialmente zero visíveis e nenhum concluído.
mode=stagger
state=ready
visible=0/3
completed=(none)
- Start em Staggered starts: start beta pode vir antes de done alpha.
- Final: state=done, visible=3/3 e completed=alpha,beta,gamma. Start volta a habilitar.
- Wait for completion reinicia. Depois start alpha → done alpha → start beta → done beta → start gamma → done gamma.
- Reset durante execução restaura oculto. Esperar não deve reviver efeitos antigos. Inicie novamente.
- Com movimento reduzido no sistema ou ferramentas, tudo aparece imediatamente e Reduced motion: shown immediately.
Cliques múltiplos e reinício
Start é desabilitado e a função confere busy. Chamadas programadas também não empilham sequências. Conclusões são contadas por elemento; um callback não conclui a coleção inteira.
.stop(true, true) limpa espera e leva o efeito atual ao fim. Reset muda primeiro generation para invalidar callbacks antigos, depois conclui e oculta. jumpToEnd pode chamar conclusão: não o faça antes de invalidar.
Evita estados e filas residuais na repetição. clearQueue sozinho não para o efeito ativo. setTimeout separados precisariam de cancelamento próprio; aqui delay usa fx.
.queue() registra e chama next() para continuar ao fadeIn. Sem next(), a fila para. Em série, só a conclusão inicia o próximo índice.
Preferências e layout real
prefers-reduced-motion reduce pula espera e fade, estabelecendo o final imediatamente. Afeta apenas o exemplo, não efeitos globais. Decoração não deve atrasar informação importante.
Mostrar de display:none cria espaço e move conteúdo posterior. Reserve espaço ou escolha outra técnica para estabilidade. Controles ocultos também exigem planejamento de teclado e foco.
Com adições dinâmicas, redefina coleção e contagem de conclusões. $items mantém os três iniciais sem novos automaticamente. Decida repetir tudo ou animar novos e ajuste filas e reinício.




