Gatsbyサイトのプリローダーの作成


導入


ギャツビーのサイトはデザインによって速いofficial website 個人的に私はその声明に同意することができます.しかし、何か理由があるかもしれないが、ウェブサイトの一部がまだ荷を積んでいる間、あなたが簡単にページローダー(または、私はそれを呼び出して、プレローダー)を表示したい場所の前に状況に遭遇したかもしれません.

このポストでは、ページの内容をオーバーレイし、ドキュメントが準備されるとフェードアウトする簡単なカスタマイズ可能なプリローダーを作成する手順を実行します.最後に、ブラウザで無効になっているユーザーのフォールバックサポートも追加します.完全なコードはsummary section . 始めましょう!

実装


Creating preloader component


プリローダーの視覚部分は、親要素とカスタム内なるコンテンツから構成されます.インスピレーションのために、私は単純なものを提供していますlogo placeholder アニメーションは、しかし、カスタマイズしたり、より良いあなた自身のニーズに合わせて交換を感じる.
ギャツビーは1セットを提供しているのでserver rendering APIs , 我々は、利用するgatsby-ssr.js ファイルとその関数.最初に、親と一緒にJSXコンポーネントを作成しますdiv 要素を指定し、preloader . その中で、私たちはカスタムコンテンツを定義します.
このコンポーネントを最終HTMLに追加するには、setPreBodyComponents ギャツビーの機能onRenderBody イベントは、サーバー側のレンダリング中に呼び出されます.最後のステップとして我々は完全にするために反応をインポート:

ギャツビーSSR.js
const React = require("react")

exports.onRenderBody = ({
  setPreBodyComponents
}) => {
  setPreBodyComponents([
    <div id="preloader">
      {/* Optional: */}
      <img src="/images/logo.png" alt="logo" style={{"height": "calc(3.23625vw + 77.86408px)"}} />
      <div className="preloader_animation"></div>
    </div>
  ])
}
次に、このコンポーネントのスタイルを追加します.もう一度、内部のコンテンツスタイリングはあなた次第です、そして、私のデモスタイルはコードブロックの底で見つかります:

src/style/preloader.SCSS
body {
  #preloader {
    position: fixed;
    display: none;
    top: 0;
    left: -10%;
    right: -10%;
    height: 0;
    margin-left: calc(100vw - 100%);
    overflow-x: hidden;
  }

  &.preloader_active {
    height: 100vh;
    overflow-y: hidden;

    #preloader {
      height: auto;
      bottom: 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background-color: #27135c;
      z-index: 9999;
      display: flex;
      overflow: hidden;
    }
  }

  &.preloader_ready {
    height: auto;
    overflow-y: auto;

    #preloader {
      animation: preloaderLeaving 0.5s forwards;

      @keyframes preloaderLeaving {
        0% {
          opacity: 1;
        }
        100% {
          opacity: 0;
        }
      }
    }
  }
}

// Optional:
body {
  #preloader {
    img {
      z-index: 120;
    }

    .preloader_animation {
      position: absolute;
      width: calc(3.23625vw + 77.86408px);
      height: calc(3.23625vw + 77.86408px);
      border: 5px solid #ffffff;
      border-radius: 50%;
      opacity: 0;
      z-index: 110;
      animation: preloaderAnimation 1.5s ease-out infinite 0s;

      @keyframes preloaderAnimation {
        0% {
          transform: scale(.1);
          opacity: 0.0;
        }
        50% {
          opacity: 1;
        }
        100% {
          transform: scale(1.2);
          opacity: 0;
        }
      }
    }
  }
}
このファイルを最後のHTMLにインポートするのを忘れないようにしましょうgatsby-browser.js ファイル

ギャツビーブラウザ.js
import "./src/styles/preloader.scss"

機能の追加


スタイルシートに気づいたかもしれませんが、現在使われていないいくつかのクラスを定義していますpreloader_active and preloader_ready . これらのそれぞれは、プリローダのライフサイクルでステージにバインドされます.

アクティブ


これはスタートクラス/ステージです.If the body 要素はこのクラスを含みます、プレローダーは見えて、ページ内容を覆います.このクラスを追加するには、gatsby-ssr.js 次のように追加します.

ギャツビーSSR.js
// ...
exports.onRenderBody = ({
  // ...
  setBodyAttributes
}) => {
  // ...
  setBodyAttributes({
    className: "preloader_active"
  })
}

準備完了


ドキュメントが準備されると、このクラスのCSSアニメーションのおかげで、プリローダーからフェーディングを開始できます.ドキュメントの状態を変更するのを待っているスクリプトで、クラスを本体に追加します.まず、与えられたスクリプトを作成しなければなりません:

静的/スクリプト/プリローダー.js
var body = document.querySelector("body");
document.onreadystatechange = function () {
  if (document.readyState === "complete") {
    body.classList.add("preloader_ready");
    setTimeout(function () {
      body.classList.remove("preloader_active");
      body.classList.remove("preloader_ready");
    }, 500);
  }
};
それから、スクリプトを最後のHTMLに挿入しますgatsby-ssr.js ファイルと利用可能なAPI

ギャツビーSSR.js
// ...
exports.onRenderBody = ({
  // ...
  setHeadComponents,
  setPostBodyComponents
}) => {
  setHeadComponents([
    <link as="script" rel="preload" href="/scripts/preloader.js" />
  ])
  // ...
  setPostBodyComponents([
    <script src="/scripts/preloader.js" />
  ])
}
私たちはこのスクリプトをできるだけ早く利用できるようにしたいです.MDN Webドキュメントのコンテンツプリローディングについてもっと読むことができますguide .

ノットサポートによる仕上げ


JavaScriptに基づいてウェブサイトを構築しているにもかかわらず、我々はまだ彼らのブラウザで無効にJSを持っている方を好むユーザーをサポートしたい.プリローダーがスクリプトに依存しているので、それは永遠に見えるままです.そして、ユーザーにどんな内容も見るのを防ぎます.我々は、単に内部の別のスタイルシートを含めることができますnoscript タグでhead ページのexplicitly allowed を返します.

スタティック/スタイル/noscript.CSS
body.preloader_active {
  height: auto;
  overflow-y: auto;
}

body.preloader_active #preloader {
  display: none;
}

ギャツビーSSR.js
// ...
exports.onRenderBody = ({
  // ..
}) => {
  setHeadComponents([
    // ...
    <noscript>
      <link rel="stylesheet" href="/styles/noscript.css" />
    </noscript>
  ])
  // ...
}

概要


我々は正常に我々のギャツビーのサイトにプリローダーを追加しました.サイトに入ると、プリローダはドキュメントが準備されるまでコンテンツをオーバーレイし、それからフェードアウトします.ユーザーがブラウザでJSを無効にした場合、プリローダーはスタイルシートを介して非表示になります.
以下に、追加または変更したファイルをすべて見つけることができます.
折りたたみ可能

ギャツビーSSR.js
const React = require("react")

exports.onRenderBody = ({
  setHeadComponents,
  setPreBodyComponents,
  setBodyAttributes,
  setPostBodyComponents
}) => {
  setHeadComponents([
    <link as="script" rel="preload" href="/scripts/preloader.js" />,
    <noscript>
      <link rel="stylesheet" href="/styles/noscript.css" />
    </noscript>
  ])
  setPreBodyComponents([
    <div id="preloader">
      {/* Optional: */}
      <img src="/images/logo.png" alt="logo" style={{"height": "calc(3.23625vw + 77.86408px)"}} />
      <div className="preloader_animation"></div>
    </div>
  ])
  setBodyAttributes({
    className: "preloader_active"
  })
  setPostBodyComponents([
    <script src="/scripts/preloader.js" />
  ])
}


ギャツビーブラウザ.js
import "./src/styles/preloader.scss"

src/style/preloader.SCSS
body {
  #preloader {
    position: fixed;
    display: none;
    top: 0;
    left: -10%;
    right: -10%;
    height: 0;
    margin-left: calc(100vw - 100%);
    overflow-x: hidden;
  }

  &.preloader_active {
    height: 100vh;
    overflow-y: hidden;

    #preloader {
      height: auto;
      bottom: 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      background-color: #27135c;
      z-index: 9999;
      display: flex;
      overflow: hidden;
    }
  }

  &.preloader_ready {
    height: auto;
    overflow-y: auto;

    #preloader {
      animation: preloaderLeaving 0.5s forwards;

      @keyframes preloaderLeaving {
        0% {
          opacity: 1;
        }
        100% {
          opacity: 0;
        }
      }
    }
  }
}

// Optional:
body {
  #preloader {
    img {
      z-index: 120;
    }

    .preloader_animation {
      position: absolute;
      width: calc(3.23625vw + 77.86408px);
      height: calc(3.23625vw + 77.86408px);
      border: 5px solid #ffffff;
      border-radius: 50%;
      opacity: 0;
      z-index: 110;
      animation: preloaderAnimation 1.5s ease-out infinite 0s;

      @keyframes preloaderAnimation {
        0% {
          transform: scale(.1);
          opacity: 0.0;
        }
        50% {
          opacity: 1;
        }
        100% {
          transform: scale(1.2);
          opacity: 0;
        }
      }
    }
  }
}

静的/スクリプト/プリローダー.js
var body = document.querySelector("body");
document.onreadystatechange = function () {
  if (document.readyState === "complete") {
    body.classList.add("preloader_ready");
    setTimeout(function () {
      body.classList.remove("preloader_active");
      body.classList.remove("preloader_ready");
    }, 500);
  }
};

スタティック/スタイル/noscript.CSS
body.preloader_active {
  height: auto;
  overflow-y: auto;
}

body.preloader_active #preloader {
  display: none;
}

静的/画像/ロゴ.PNG