web制作

ローディング画面を初回の一回のみ出す方法【JavaScriptとsessionStrage】

ローディング画面を初回の一回のみ出す方法【JavaScriptとsessionStrage】
本ページにはプロモーションが含まれています。

ローディング画面を何度も出していると「煩わしい」と感じますよね。この記事では、

初回の1回のみローディング画面(アニメーション)を出し、ブラウザを閉じない限り、ローディングは発生しなくする

この処理を、「セッション」と「JavaScript」を用いて実装していきます。

しょーご

この記事を書いたのは
しょーご@samurabrass

当ブログ「しょーごログ」の運営者。2018年からWeb制作・フロントエンドエンジニアとして主にWordPressでのサイト制作やシステム開発のフロントエンドを担当。同時にブログとYouTubeで情報発信を行っている。駆け出しエンジニアのコーディング課題添削も行い、スクール講師を4年以上している経験を活かした分かりやすい記事制作を心がけている。

CookieとsessionStrageとlocalStrageの違い

セッションとはなんでしょうか?似たものに、「Cookie」「ローカルストレージ」などがありますので、比べてみます。

データの保存期間が最重要です。

特徴Cookieセッションストレージローカルストレージ
データの保存期間ブラウザの設定に依存(期限を設定可能)セッション終了時に消去(ブラウザを閉じると消去)ユーザーが明示的に消去するまで永続的に保存
利用目的ユーザー設定、トラッキング、認証などセッション中のデータの一時的な保存永続的なデータの保存、オフラインアプリケーションなど
利用上の制限1ドメインあたりのCookie数に制限あり通常はデータサイズが5MB以下に制限される通常はデータサイズが5MB以下に制限される
利用場面小規模なデータの保存や短期間の情報保持に適用セッション中の情報や一時的な操作の保存に適用データの永続的な保存や大規模な情報の保持に適用
データの保存場所ブラウザ内のCookieストレージブラウザ内のセッションストレージブラウザ内のローカルストレージ

今回の場合、

ブラウザを閉じるまではローディング二回目を起こさない。ブラウザを閉じてもう一度アクセスしたら、再度ローディングが発火

こういった仕様なので、JavaScriptでsessionStrageを使用します。

sessionStrageでの処理の流れ

流れとしては、

  1. sessionStrageのフラグをチェック(sessionStorage.getItem(‘hoge’);
  2. もしフラグがない(初回訪問)場合、ローディング処理
  3. もしフラグがある(二回目以降)場合、ローディングしない

こういった流れがイメージできます。

// セッションストレージからフラグを取得
const isFirstLoad = sessionStorage.getItem('isFirstLoad');

// ページの読み込みが完了したときに実行される関数
window.addEventListener('load', function() {
  // フラグがない場合(初回アクセス時)
  if (!isFirstLoad) {
    // 初回アクセス時の処理を記述
    // 例: ローディング画面の表示、セッションストレージへのフラグの保存など
    console.log('初回アクセスです');
    
    // セッションストレージにフラグを保存
    sessionStorage.setItem('isFirstLoad', true);
  } else {
    // 2回目以降のアクセス時の処理を記述
    console.log('2回目以降のアクセスです');
  }
});

このコードの中に、ローディング処理を入れていけばいいです。

初回のみローディング画面を出すコード

See the Pen Untitled by samuraibrass (@samuraibrass) on CodePen.

まずHTMLとCSSを見てみますが、ローディング後に出現するコンテンツはdisplay noneにしておき、JS無しのデフォルトではローディング画面が全体を覆い、何も見えないようにしています。

<div class="loading">
    <img src="https://shogo-log.com/wp-content/uploads/2024/03/1544077823-1.png" alt="">
  </div><!-- /.loading -->
  <div class="contents hidden">
    <h1>コンテンツ</h1>
  </div>
.hidden {
  display: none;
}
.loading {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  background: #fff;
  z-index: 2147483647;
  display: grid;
  place-content: center;
  opacity: 0; /* 初期状態は透明にする */
  transition: opacity 0.5s ease; /* アニメーションを適用 */
  pointer-events: none; /* 背後のコンテンツにマウスイベントが影響しないようにする */
}
.loading.active {
  display: grid;
  opacity: 1;
  transition: opacity 0.5s ease; /* アニメーションを適用 */
}
img {
  width: 312px;
  height: 312px;
}
/* JS が無効なときのスタイル */
@media (scripting: none) {
  .loading {
    display: none;
  }
.hidden {
display: block;
}
}

次にJavaScriptを見ていきます。

//セッションストレージからフラグを取得:
const isFirstLoad = sessionStorage.getItem('isFirstLoad');

ウェブページのセッションストレージから、”isFirstLoad” というキーで保存されている値を取得します。この値は、ページが初回アクセスされたかどうかを示すフラグです。

// ページの読み込みが完了したときに実行される関数:
window.addEventListener('load', function() {
    // ここに処理を記述
});

window オブジェクトの load イベントが発生したときに、指定された関数が実行されます。この関数内に、ページの読み込み後に行いたい処理を記述します。

// 初回アクセス時の処理:
if (isFirstLoad !== 'true') {
    // 初回アクセス時の処理を記述
} else {
    // 2回目以降のアクセス時の処理を記述
}

セッションストレージから取得したフラグが ‘true’ でない場合、つまり初回アクセス時の処理が実行されます。

それ以外の場合、2回目以降のアクセス時の処理が実行されます。

// 初回アクセス時の処理:
const loadingElement = document.querySelector('.loading');
loadingElement.classList.add('active');

ローディング画面を表示するために、loading クラスが付いた要素を取得し、active クラスを追加します。

これにより、CSSでスタイルが適用され、ローディング画面が表示されます。

// ローディング画面の非表示:
setTimeout(function() {
    loadingElement.classList.remove('active');
    const contentsElement = document.querySelector('.contents.hidden');
    contentsElement.classList.remove('hidden');
    sessionStorage.setItem('isFirstLoad', 'true');
}, 2000);
setTimeout(function() {
    loadingElement.style.display = 'none';
}, 2500);

2秒後に、ローディング画面を非表示にする処理が実行されます。まず、active クラスが削除され、ローディング画面が非表示になります。

その後、さらに0.5秒後に、display: none; スタイルが適用され、要素が完全に非表示になります。

0.5秒後に、display: none; を適用するのは、opacityを0にするだけでは、画面からローディング画面が完全に消えないからです。

かといってdisplay: none; だけを使うと今度はアニメーションで消えないので、やむなくopacityで見た目上消してから、display: none;で完全にローディング画面を抹消しています。

// 2回目以降のアクセス時の処理:
const contentsElement = document.querySelector('.contents.hidden');
contentsElement.classList.remove('hidden');

ページが初回アクセスではない場合、つまり2回目以降のアクセス時には、.contents.hidden クラスを持つ要素を取得し、

hidden クラスを削除してコンテンツを表示します。

このようにして、初回アクセス時にローディング画面を表示し、2秒後にフェードアウトさせて非表示にする処理が実装されています。

一瞬だけサイトが表示されてしまう場合

ローディングの前に一瞬サイトが表示されてしまう場合、以下のコードも試してみてください。

<!-- HTML -->
<div class="loading" id="loading">
  <img src="https://shogo-log.com/wp-content/uploads/2024/03/1544077823-1.png" alt="">
</div>
<div class="contents hidden" id="contents">
  <h1>コンテンツ</h1>
</div>

/* CSS */
.hidden { display: none; }

/* デフォルトはローダー表示 */
.loading {
  position: fixed; /* absolute だと body の高さに依存してズレる可能性 */
  inset: 0;        /* left:0; top:0; width:100%; height:100% と同義 */
  background:#fff;
  z-index:2147483647;
  display:grid;
  place-content:center;
  opacity:1;
  transition:opacity .5s ease;
}

.loading.fade-out {
  opacity:0;
  pointer-events:none;
}

/* JS 無効対策(同じ) */
@media (scripting:none) {
  .loading { display:none; }
  .hidden  { display:block; }
}
// JS(defer で読み込み、DOMContentLoaded で発火)
document.addEventListener('DOMContentLoaded', () => {
  const loading   = document.getElementById('loading');
  const contents  = document.getElementById('contents');

  // 初回判定
  const first = sessionStorage.getItem('firstVisit') !== 'done';

  if (first) {
    // ローダーを 2 秒だけ表示
    setTimeout(() => {
      loading.classList.add('fade-out');
      contents.classList.remove('hidden');
      sessionStorage.setItem('firstVisit', 'done');
    }, 2000);

    // CSS transition が終わったら完全に消す
    loading.addEventListener('transitionend', () => loading.remove());
  } else {
    // 2回目以降は即座にコンテンツ表示
    loading.remove();
    contents.classList.remove('hidden');
  }
});

意外に使われる一回だけのローディング画面

ローディング画面を都度出すのは煩わしいため、今回の初回のみローディング画面を出す手法は習得しておきたいです。その割にデイトラWeb制作コースのようなプログラミングスクールでも意外に教えられることが無いですし、Web制作を独学している場合は実務まで出くわさないことも多いでしょう。

しょーごログのWeb制作ロードマップで紹介しているコーディング中級Ex課題ではこの仕様を求めているため、ぜひ挑戦してみてください。

模擬案件チャレンジ開催のお知らせ

模擬案件編(旧超実践編)では納期厳守の模擬案件を経験し、実務で求められるレベルの「質」と「スピード」を体感することができます。

デザインカンプからのコーディング 模擬案件編

最近は実案件のノウハウも多いですが、「納期が短い案件の中で、求められる品質で納品」する自信はありますか?

この課題では、極限まで実案件の緊張感を意識してもらうために、以下が合格条件となっています。

  • 初稿提出は9日以内
  • 修正点は10箇所以内

この模擬案件は以下のような方におすすめです。

  • 学習はだいたい終わったけど、納期までに納品できるか不安
  • 中々継続と紹介で案件が回らない

このような中級者を飛躍させる模擬案件編、受講には推奨レベルがありますので、詳細はリンク先よりご確認下さい。

しょーご

あなたの挑戦を待っています!!

\レビューを受けて圧倒的な自信を身につける!/

応援して頂ける方へ

ご寄付を頂けると今後の更新の励みになります!

🍺 ビールをプレゼントする

あなたに是非読んでほしい記事です!