jQuery / 要素を順番に表示する
.delay(index * gap).fadeIn(duration)で開始時刻をずらせます。効果時間が間隔より長いと重なります。前の表示が完全に終わってから次へ進むなら、完了コールバックから次要素を実行します。
開始間隔と完了順
.delay()は各要素の列で次処理を待たせます。集合全体の共通列ではありません。同じ待ち時間だけでは同時期になり、indexを掛けると開始差になります。JavaScript全体は止めません。
間隔200ms、.fadeIn()時間400msです。時間差方式はAlpha完了前にBeta開始、逐次方式は完了後さらに200ms待ちます。ブラウザー負荷による差があるため厳密時刻の保証ではありません。
.each()は集合順です。#items直下.itemはAlpha・Beta・Gammaですが、並べ替えた集合やCSS配置では見える順と違う場合があります。読者の順序を決めます。
比較できる完全な例
全コードをUTF-8のappearance-demo.htmlへ保存し開きます。インターネットから公式jQuery完全版4.0.0を読みます。時間付きeffectsが必要でslimにしません。サーバーや導入は不要です。Windows Edge、3.7.1・4.0.0で順序と復元・再生を確認しました。
HTMLは表示状態で、準備スクリプト後に隠します。読込失敗だけでCSSにより内容が永久に隠れる構成ではありません。次は初期化後です。
<!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>
初期は表示0、完了なしです。
mode=stagger
state=ready
visible=0/3
completed=(none)
- Staggered startsでStart。start betaがdone alphaより先に出て効果が重なり得ます。
- 終了はstate=done、visible=3/3、completed=alpha,beta,gammaでStart再使用可です。
- Wait for completionに変えると復元します。Start後はstart alpha → done alpha → start beta → done beta → start gamma → done gammaです。
- 途中Resetで初期非表示へ戻ります。待っても古い効果が復活せず、Startで再生できます。
- OSや開発者ツールで動きを減らしてStartすると即時表示しReduced motion: shown immediatelyです。
連打と初期化
実行中Startを無効化し関数入口でもbusyを確認します。コードからの再呼出しでも積みません。各要素完了を集め、一個の完了を全体完了としません。
.stop(true, true)は待機を消し現在効果を終端へ整理します。Resetは先にgenerationを変え旧コールバックを無効にし、その後整理・非表示にします。jumpToEndは完了を呼び得るため順番を逆にしません。
残った状態と列が再生へ混ざるのを防ぎます。clearQueueだけでは現在効果は止まりません。別setTimeoutなら別途取消しが必要で、例は基本fx列のdelayです。
ログ用.queue()は開始記録後next()を呼びfadeInへ進みます。省くと列が止まります。逐次方式は完了から次インデックスだけを開始します。
設定と実画面
prefers-reduced-motionがreduceなら待ちとフェードを省き最終状態にします。例だけの設定で全体効果は変えません。装飾のため重要情報へのアクセスを遅らせません。
display:noneから出すと空間が増え後続が動きます。位置を保つなら場所を確保するか別方式を検討します。入力などがある場合は隠したときのキーボードとフォーカスも設計します。
動的追加には集合と完了数を再定義します。$itemsは初期三つで自動追加しません。全部再生か新規だけか決め、復元と列管理を合わせます。




