
Shopifyサイトにローディング・アニメーションを実装する方法
今回はページを読み込んでいる時に表示するローディング・アニメーションを実装する方法をご紹介します。
ローディング・アニメーションがデフォルトで実装されていないShopifyのテーマ(例えばShopify公式テーマのDebut)のときに、次の方法でローディング・アニメーションを実装することができます。
それではまず、Shopifyの管理画面から「テーマ」→ 「アクション」→「コードを編集する」と進んで、Shopifyのテキストエディタのページを開きます。
Theme Kitをすでに使用していて、ローカル環境でVS Codeなどご自分の好きなテキストエディタで編集される方はそちらでコードを編集してください。
今回の記事ではShopifyのテキストエディタでコードをいじっていくことにします。
Shopifyのテキストエディタのページを開いたら、
左側のナビゲーションメニューの箇所で「Layout」「Templates」「Sections」と続くフォルダの次にある「Snippets」のフォルダの部分にある「新しいsnippetsを追加する」をクリックして、名前は何でも良いのですが分かりやすいようにloaderという名前にします。
loader.liquidファイルが作成されたら、下にloader用のコードを用意しましたのでそのコードをloader.liquidにコピペします。
<svg>タグから</svg>の閉じタグまでのSVGコードはご自身の好きなものを挿入して下さい。
<aside id="loader" aria-hidden="true">
<div class="loader">
<div class="loader__inner">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
style="margin: auto; background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; display: block; shape-rendering: auto;"
width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<path d="M10 50A40 40 0 0 0 90 50A40 42 0 0 1 10 50" fill="#544747" stroke="none">
<animateTransform attributeName="transform" type="rotate" dur="1s" repeatCount="indefinite" keyTimes="0;1"
values="0 50 51;360 50 51"></animateTransform>
</path>
</svg>
</div>
</div>
<style>
@keyframes fadeInloader {
0% {
opacity: 0;
visibility: hidden;
}
100% {
opacity: 1;
visibility: visible;
}
}
@keyframes fadeOutloader {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
.loader {
position: fixed;
z-index: 2147483647;
top: 0;
left: 0;
background-color: rgba(230, 230, 230, 1);
width: 100vw;
height: 100vh;
opacity: 1;
visibility: visible;
will-change: opacity, visibility;
animation: fadeOutloader 1s forwards;
animation-delay: 6s;
pointer-events: none;
}
.loader--fadeOut {
animation: fadeInloader 1s forwards;
}
.loader__inner {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.loader__image {
opacity: 98%;
width: 150px;
height: auto;
max-height: 100%;
}
</style>
<script>
(function () {
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
function removeLastSlash(str) {
let retStr = str;
if (str.charAt(str.length - 1) === '/') {
retStr = str.slice(0, -1);
}
return retStr;
}
function containsExcluded(class_list, excluded_classes) {
for (let el of class_list) {
for (let elExcluded of excluded_classes) {
if (el.includes(elExcluded)) return true;
}
}
return false;
}
document.addEventListener('DOMContentLoaded', () => {
const links = document.querySelectorAll('a');
const preloaderHtml = document.getElementsByClassName('loader')[0];
const windowLocationPathnameTrim = removeLastSlash(window.location.pathname);
const domain = '{{shop.domain}}';
const permanent_domain = '{{shop.permanent_domain}}';
const excluded_classes = ["js-", "cart", "ajax", "toggle"];
if (preloaderHtml) {
links.forEach(link => {
const isExcluded = containsExcluded(link.classList, excluded_classes);
const url = link.getAttribute('href');
const isNewWindow = link.getAttribute('target');
const isSameDomain = (link.hostname === domain || link.hostname === permanent_domain);
const linkPathnameTrim = removeLastSlash(link.pathname);
let navigatingWithinPage = true;
if (isSameDomain) {
navigatingWithinPage = url.startsWith('#') ||
(linkPathnameTrim === windowLocationPathnameTrim && url.includes((link.pathname + '#')));
}
if (!isNewWindow && isSameDomain && !navigatingWithinPage && !isExcluded) {
link.addEventListener('click', function (event) {
event.preventDefault();
const url = this.getAttribute('href');
preloaderHtml.classList.add('loader--fadeOut');
setTimeout(() => window.location.href = url, 1 * 1000)
})
}
})
}
});
// fix for safari
window.addEventListener('pageshow', function (event) {
if (event.persisted) {
const preloaderHtml = document.getElementsByClassName('loader')[0];
preloaderHtml.classList.remove('loader--fadeOut');
}
});
})();
</script>
</aside>
筆者がオススメなのは下記のローディング・アニメーションが簡単につくることができるloading.ioです。
有料のアイコン、無料のアイコンどちらでも
アイコンのサイズ・カラー・スピード、背景色、角の丸みの太さ、
背景色を透明にするかどうか等
あらゆる部分が上の管理画面からカスタマイズ可能です。
今回はベーシックなローディング・アニメーションを選びました。
loader.liquidファイルに上記のコードをコピペしたら、次にそのスニペットファイルを反映させるために下のコードをtheme.liquidファイルにコピペします。
{% include 'loader' %}
theme.liquidファイルは一番上の「Layout」フォルダの中にあります。
コピペする場所は上のスクリーンショットの画像のとおり、<body 〜〜>タグの直後です。
Snippets スニペットについては今回の記事では詳しく説明しませんが、
簡単に言うと、snippetsフォルダの中に作成したliquidファイルは
{% include %}というliquidタグで呼び出すことができます。
そうすると、ページを読み込むときにローディング・アニメーションが表示されるようになったかと思います。
<svg>タグから</svg>の閉じタグまでのSVGコードをloading.ioで自分の好きなローディング・アニメーションで表示させてものが下記のページになります。
https://in-wonder-with-osho.com/
このサイトはフォントをAdobe FontsのTypekit Webフォントを読み込んでおり、再描画のチラツキ(いわゆる「Flash Of Unstyled Text (FOUT)」)を無くすためにローディング・アニメーションを読み込んでいます。
Webフォント読み込み時の「再描画ちらつき」をなくす方法については下記の記事が分かりやすいので、参考にしてみてください。
Webフォント読み込み時の「再描画ちらつき」をなくす方法
Webフォントによるちらつきをなくす方法(ネット低速環境も考慮)
それでは今回はShopifyサイトにローディング・アニメーションを実装する方法をご紹介しました。
Nirvana Lab.ではShopifyでのECサイトの制作・構築、Shopifyのテーマカスタマイズ、他社ECプラットフォームからのShopifへの移行だけでなく
翻訳・ローカライゼーションもに対応しておりますので、まずは何でもお気軽にご相談くださいませ。
https://nirvana-lab.com/portfolio/
Twitterでも軽くですが、発信しておりますので
お気軽にフォローをおねがいします!