(Sample)

今回は「ローディング画面付きギャラリー」のコードを解説していきます。

読み込み中にスピナー(くるくる回る表示)を出して、画像が全部読み終わったらギャラリーを表示する構成です。とても実用的なテクニックなので、ぜひ覚えていってください!


ページの構造を確認しよう(HTML編)

HTMLでは、パンくずリスト・ローディング画面・ギャラリー本体の3つのブロックが定義されています。

ギャラリーのHTML構造(抜粋)

<!-- ローディング画面 -->
<div id="loading">
  <div class="spinner-border text-primary" role="status">
    <span class="visually-hidden">Loading...</span>
  </div>
</div>

<!-- ギャラリーコンテンツ -->
<div id="content" style="display: none">
  <div class="container mt-5">
    <div class="row">
      <div class="col-lg-3 col-md-4 col-6 mb-4">
        <img src="https://picsum.photos/200/300?random=1" class="img-fluid" />
      </div>
      <!-- 以下略 -->
    </div>
  </div>
</div>

ポイント解説

要素説明
#loadingローディング中に表示されるエリア。常に前面に出るよう z-index: 9999 を指定。
.spinner-borderBootstrap のスピナーコンポーネント。読み込み中のビジュアル演出。
#content本来のコンテンツ(ギャラリー)。最初は非表示。画像がすべて読み込まれたら表示される。

ローディング画面の見た目をつくる(CSS編)

#loading {
  position: fixed;
  width: 100%;
  height: 100%;
  background: white;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

この部分は画面いっぱいに白背景+中央にスピナーを表示する設定です。

position: fixedとは?

画面をスクロールしても常に同じ位置に固定表示される指定です。

z-index: 9999とは?

レイヤーの重なり順を指定するプロパティです。数値が大きいほど手前に表示されます。


動きを制御するJavaScriptの仕組み

今回のキモになる部分は、画像が全部読み込まれるまでローディング画面を表示する処理です。

function imagesLoaded(parentNode) {
  const imgElements = parentNode.querySelectorAll("img");
  for (let img of imgElements) {
    if (!img.complete || img.naturalHeight === 0) {
      return false;
    }
  }
  return true;
}

どうやって「全部読み込んだか」を判断しているの?

  • img.complete:画像の読み込みが完了していれば true
  • img.naturalHeight === 0:画像が破損していないかをチェック

すべての画像が complete=true かつ naturalHeight > 0 であれば、表示準備OK!ということですね。


表示切り替え処理の全体像

window.addEventListener("load", function () {
  const content = document.getElementById("content");

  if (imagesLoaded(content)) {
    // 画像がすでに全部読み込まれていたら即表示
    document.getElementById("loading").style.display = "none";
    content.style.display = "block";
  } else {
    // 読み込み中なら画像ごとにイベントを仕込む
    const imgElements = content.querySelectorAll("img");
    let loadedCount = 0;
    imgElements.forEach((img) => {
      img.addEventListener("load", () => {
        loadedCount++;
        if (loadedCount === imgElements.length) {
          document.getElementById("loading").style.display = "none";
          content.style.display = "block";
        }
      });
    });
  }
});


処理の流れを図で確認しよう

ページ読み込み開始
   ↓
ローディング画面表示
   ↓
ギャラリー内のすべての画像をチェック
   ↓
全部読み込んだら...
   ↓
ローディング非表示 → ギャラリー表示

よくある疑問と答え

Q1. なぜ window.onload ではなく DOMContentLoaded を使わないの?

DOMContentLoaded は「HTMLの読み込み完了」を意味し、画像は読み込み対象に含まれません。画像も含めた「完全な読み込み」を確認したい場合は window.addEventListener("load", ...) を使うのが正解です!


応用してみよう!

このパターンを使えば、他にも応用できます!

応用例内容
動画プレイヤーのローディング動画ファイルの読み込み完了を検知してから表示
SPAの遷移先で表示シングルページアプリケーションのページ遷移に合わせてローディング演出
画像にフェードイン効果を追加読み込み後に opacity を滑らかに変化させる

今後の学習のステップ

この実装で習得できた技術は以下の通りです:

  • 画像の読み込み状況の確認方法(completenaturalHeight
  • JavaScriptでのDOM操作
  • Bootstrapの活用(スピナー・グリッドシステム)

次はぜひこんなことに挑戦してみましょう!

  • フェードインやスライド表示などCSSトランジションとの組み合わせ
  • 画像が多いときのLazy Load(遅延読み込み)対応
  • プリローダーをSVGやロゴ付きでカスタムしてみる

もっと魅力的なUIを作るために、ぜひ実験してみてください!わからないところがあれば、いつでも聞いてくださいね。