Webページの読み込み中にローディング画面を表示することで、ユーザーが「止まっているのか?」と不安にならないようにできます。本記事ではページ読み込み中のオーバーレイ・スピナー・Ajax通信中の表示・フェードアウトまで解説します。
この記事でわかること
- ページ読み込み中にローディング画面を表示する方法
- CSSスピナーアニメーションの実装
- Ajax通信前後にローディングを表示/非表示する方法
- グローバルAjaxイベント(ajaxStart/ajaxStop)の活用
- ローディング画面のフェードアウトと非表示のポイント
1. ページ読み込み中のローディング画面
最もシンプルな実装です。HTMLに#loading要素を置き、ページ読み込み完了(window.load)時にフェードアウトします。
<!-- ローディングオーバーレイ(bodyの先頭に置く) --> <div id="loading"> <div class="spinner"></div> </div>
#loading {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(255, 255, 255, 0.95);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
/* CSSスピナー */
.spinner {
width: 48px; height: 48px;
border: 5px solid #e2e8f0;
border-top-color: #0284c7;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
// window.load: 画像・CSSを含む全リソースの読み込み完了後に発火
$(window).on('load', function () {
$('#loading').fadeOut(400);
});
// タイムアウト保険: 10秒後には必ず非表示(ネットワーク障害対策)
setTimeout(function () {
$('#loading').fadeOut(400);
}, 10000);
$(document).ready() ではなく $(window).on(“load”) を使う
$(document).ready() はDOMが構築された時点で発火するため、画像やCSSの読み込みが完了していません。ローディング画面の非表示には $(window).on("load") を使ってページの全リソース読み込み完了を待ちます。2. Ajax通信中にローディングを表示する
Ajax通信の前後にshow()/hide()でローディングを制御するパターンです。
function fetchData() {
$('#loading').show();
$.ajax({
url: '/api/data',
method: 'GET',
success: function (data) {
// データを表示する処理
console.log(data);
},
error: function () {
alert('データの取得に失敗しました');
},
complete: function () {
$('#loading').hide(); // 成功・失敗にかかわらず必ず非表示
}
});
}
3. グローバルAjaxイベントで自動制御
ページ内の全Ajaxリクエストに対して自動でローディングを表示したい場合は、グローバルAjaxイベントを使います。
// 全Ajaxリクエスト開始時に自動表示
$(document).on('ajaxStart', function () {
$('#loading').fadeIn(200);
});
// 全Ajaxリクエスト完了時に自動非表示
$(document).on('ajaxStop', function () {
$('#loading').fadeOut(400);
});
ajaxStart/ajaxStopの注意点
ajaxStart はその時点でAjaxリクエストが1件もない状態から最初のリクエストが始まったときに発火します。ajaxStop は全てのAjaxリクエストが完了したときに発火します。複数リクエストが同時に走っていても1回だけ発火するため、カウンター管理が不要です。4. ボタンクリック時のローディング表示
「送信中…」のインジケーターをボタン内に表示するパターンです。
<button id="submit-btn">送信する</button>
$('#submit-btn').on('click', function () {
var $btn = $(this);
var originalText = $btn.text();
$btn.prop('disabled', true)
.html('<span class="spinner-sm"></span> 送信中...');
$.ajax({
url: '/api/submit',
method: 'POST',
complete: function () {
$btn.prop('disabled', false).text(originalText);
}
});
});
まとめ
| 場面 | 実装方法 |
|---|---|
| ページ全体の読み込み中 | $(window).on(“load”)でfadeOut() |
| 特定のAjaxリクエスト中 | beforeSend/completeでshow()/hide() |
| 全Ajaxリクエストに対応 | ajaxStart/ajaxStopイベント |
| ボタン送信中 | disabled + テキスト変更 |
関連記事: jQueryのアニメーション完全ガイド(fadeIn/fadeOut) / jQueryでクリックを禁止・無効化する方法
よくある質問(FAQ)
Q$(window).on(“load”)と$(document).ready()の違いは?
A
$(document).ready() はDOMのみの構築完了時に発火します(画像はまだ読み込み中の場合あり)。$(window).on("load") は画像・CSS・スクリプトを含む全リソースの読み込み完了後に発火します。ローディング画面の非表示には後者を使います。Qローディング画面が消えない場合は?
A巨大な画像や重いリソースがあると
window.load がなかなか発火しないことがあります。タイムアウト処理(setTimeoutで強制非表示)を実装して、いつまでも表示され続けることがないようにしてください。QCSSスピナーはどのブラウザで使えますか?
A
animation と border-radius を使うスピナーはIE10以上・全モダンブラウザで動作します。IE11対応が不要なら @keyframes ベースのアニメーションは問題なく使えます。QSPA(シングルページアプリ)でルート遷移時にも表示するには?
ASPA(React/Vue/Angularなど)では独自のルーターイベントを使います。jQueryを使っている従来型のWebサイトでは、Ajaxでコンテンツを差し替える処理の前後でshow()/hide()を呼ぶのが基本です。
Qローディング中はスクロールを禁止するには?
A
$("body").css("overflow", "hidden") でスクロールを禁止し、ローディング非表示時に $("body").css("overflow", "") で解除します。