ローディング画面を追加する方法

Cocoonカスタマイズ集
この記事は約9分で読めます。
記事内に広告が含まれています。

記事に記載したコードは、スキンに追加されています。

はじめに

フロントページ表示時に、ローディング画面(黒い背景の画面)を1回だけ表示します。

この記事では、この方法について説明します。

実装手順

以下の手順で実装します。

  • ラベル
    HTMLを追加

    ローディング画面のHTMLを以下のいずれかの方法で追加します。

    • ウィジェットを使用して追加
      外観→ウィジェット→「カスタムHTML」に以下コードを追加します。
      ウィジェットを「コンテンツ上部」に配置します。

    <div class="loader-bg">
    /* ローディング画面 */
    </div>

    • PHPのフックを使用して追加
      以下のコードをfunctions.phpに追加します。
      以下のフックを使用してローディング画面のHTMLを追加します。
      Cocoonの場合、CSSクラスcontainerの直後となります。

    add_action('wp_body_open', function () {
      ?>
      <div class="loading"></div>
      <?php
    });
  • ラベル
    JavaScriptを追加

    以下のコードをjavascript.jsに追加します。
    セッションストレージを使用して、同一ウィンドウでは1回のみ表示されるようにします。

    jQuery(function ($) {
      // セッションストレージにキーが存在しない場合
      if (!sessionStorage.getItem('visited')) {
        // ローディング画面を表示
        $('.loading').css('display', 'grid');
    
        // 2秒後にフェードアウトして非表示
        setTimeout(function () {
          $('.loading').fadeOut(1000);
        }, 2000);
    
        // セッションストレージにキーと値を保存
        sessionStorage.setItem('visited', 'first');
      }
    });
  • ラベル
    CSSを追加

    以下のコードをstyle.cssに追加します。

    .loading {
      background-color: #333;
      display: none;
      height: 100vh;
      place-content: center;
      position: fixed;
      top: 0;
      width: 100vw;
      z-index: 9999;
    }

応用:タイプライター風のローディング画面を表示する方法

任意の文字列をタイプライター風に1文字ずつ表示します。

完成イメージ

実装手順

タイプライター風に文字を表示するには、主に以下の2つの方法があります。

  1. JavaScriptで1文字ずつ出力・制御する方法
    文字列を分解してJavaScriptで制御しながら順次描画していく手法です。
    この方法は文字数やフォント(プロポーショナルフォントなど)の種類を選ばず、任意の日本語テキストでもレイアウトが崩れません。
    また、表示文字数を変更するたびにCSSの数値を調整する必要がないため、柔軟で汎用性の高い実装が可能です。
  1. CSSのアニメーション(steps)で出力する方法
    タイピング表示自体をCSSのsteps()関数と文字幅単位chに任せる軽量な手法です。
    タイピングの描画処理をCSSのみで行えるメリットはありますが、文字幅の計算上「等幅フォント(monospace)」の指定が必須となります。
    さらに、表示する文字列の長さ(文字数)に応じてCSS側の幅指定やステップ数の数値を手動で調整しなければならない点に注意が必要です。

JavaScriptで1文字ずつ出力・制御する方法

以下の手順で実装します。

  • ラベル
    JavaScriptを追加

    以下のコードをjavascript.jsに追加します。

    jQuery(function ($) {
      if ($('.loading').length) {
        if (sessionStorage.getItem('visited')) {
          // 2回目以降
          loadedPage();
        } else {
          // 1回目
          typewriter();
          sessionStorage.setItem('visited', 'first');
        }
      }
    
      // ローディング画面表示済み
      function loadedPage() {
        $('.loading').addClass('is-loaded');
      }
    
      // タイプライター
      function typewriter() {
        var time = 400;
        var moji = 0;
    
        // テキストを1文字単位に分解
        $('.loading__typing').each(function () {
          var text = $(this).text();
          var html = '';
    
          text.split('').forEach(function(t) {
            html += t !== ' ' ? `<span>${t}</span>` : t;
            moji++;
          });
    
          $(this).html(html);
        });
    
        $('.loading__typing').css('display', 'block');
        $('.loading').css('transition', '0.3s');
    
        // タイプライターアニメ
        TextTypingAnime(time);
    
        // ローディング画面終了
        setTimeout(loadedPage, (moji + 1) * time);
      }
    
      // タイプライターアニメ
      function TextTypingAnime(time) {
        $('.loading__typing').each(function () {
          var thisChild = $(this).children();
    
          // spanタグの要素に時差でフェードインを適用
          thisChild.each(function (i) {
            $(this).delay(time * i).fadeIn(time);
          });
        });
      }
    });
  • ラベル
    CSSを追加

    以下のコードをstyle.cssに追加します。

    /* ローディング画面 */
    .loading {
      align-items: center;
      background-color: #333;
      display: flex;
      height: 100%;
      justify-content: center;
      left: 0;
      opacity: 1;
      position: fixed;
      top: 0;
      visibility: visible;
      width: 100%;
      z-index: 100;
    
      /* ローディング完了時 */
      &.is-loaded {
        opacity: 0;
        visibility: hidden;
      }
    
      /* タイプライターテキスト */
      .loading__typing {
        color: #fff;
        display: none;
    
        span {
          display: none;
        }
    
        /* カーソル点滅 */
        &::after {
          animation: typinganime 0.8s ease infinite;
          content: '|';
        }
      }
    }
    
    /* 点滅アニメーション */
    @keyframes typinganime {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
  • ラベル
    HTMLを追加

    以下のコードを「カスタムHTML」ウィジェットに入力します。

    <div class="loading">
      <div class="loading__typing">Loading...</div>
    </div>

CSSのアニメーション(steps)で出力する方法

以下の手順で実装します。

  • ラベル
    JavaScriptを追加

    以下のコードをjavascript.jsに追加します。

    jQuery(function ($) {
      if ($('.loading').length) {
        if (sessionStorage.getItem('visited')) {
          // 2回目以降
          $('.loading').addClass('is-loaded');
        } else {
          // 1回目
          sessionStorage.setItem('visited', 'first');
        }
      }
    
      // タイプライターアニメーション終了時の処理
      $(document).on('animationend', '.loading__typing', function () {
        $('.loading').addClass('is-off');
      });
    
      // ローディング終了時の処理
      $(document).on('transitionend', '.loading.is-off', function () {
        $('.loading').css('display', 'none');
      });
    });
  • ラベル
    CSSを追加

    以下のコードをstyle.cssに追加します。

    /* ローディング画面 */
    .loading {
      align-items: center;
      background-color: #333;
      display: flex;
      height: 100%;
      justify-content: center;
      left: 0;
      opacity: 1;
      position: fixed;
      top: 0;
      visibility: visible;
      width: 100%;
      z-index: 100;
    
      &.is-loaded {
        opacity: 0;
        visibility: hidden;
      }
    
      /* ローディング終了 */
      &.is-off {
        opacity: 0;
        transition-delay: 1s;
        transition-duration: 1.5s;
        transition-property: opacity;
      }
    
      /* タイプライター */
      .loading__typing {
        animation: typing 3s steps(10), effect 0.5s step-end infinite alternate;
        border-right: 1px solid;
        color: #fff;
        font-family: monospace;
        font-size: 1em;
        font-weight: bold;
        overflow: hidden;
        white-space: nowrap;
        width: 10ch;
      }
    }
    
    /* テキスト表示 */
    @keyframes typing {
      from {
        width: 0;
      }
    }
    
    /* カーソル表示 */
    @keyframes effect {
      50% {
        border-color: transparent;
      }
    }
  • ラベル
    HTMLを追加

    以下のコードを「カスタムHTML」ウィジェットに入力します。

    <div class="loading">
      <div class="loading__typing">Loading...</div>
    </div>

参考:セッションストレージの保存先

セッションストレージ

図2にセッションストレージの保存先を示します。
Chromeデベロッパーツールでアプリケーション→ストレージ→セッションストレージを選択することで確認できます。

さいごに

今回紹介した方法を使えば、フロントページ表示時にローディング画面を簡単に導入できます。
セッションストレージを活用することで、毎回の表示を防ぎ、ユーザーにストレスを与えずに快適な表示ができるでしょう。

タイトルとURLをコピーしました