今回はトップページなどでよく見られる、ページローディングの実装を備忘録として残します。
目次
JavaScript ページローディング
ネイティブのJavaScriptで動かすページローディングです。
下記の流れで動作します。
- 「position: fixed;」のスタイルがあたっている、ローディングアニメーションを含んだDOM
<div class=”loading” id=”loading”>を表示する。 - ローディングの完了と同時にJavaScriptが発火、ローディングアニメーションを含んだDOM
<div class=”loading” id=”loading”>のdisplayをnoneに、opacityを0にして非表示とする。
上記の他に、同じセッション中に何度もローディング画面を出さないように、sessionStorageでローディングが表示されたかどうかを管理するようにしています。
動作サンプル
HTML
<!-- ローディング部分 START -->
<div class="loading" id="loading">
<div class="loading-animation">
<div class="loading-animation__circle"></div>
</div>
</div>
<!-- ローディング部分 END -->
<!-- ロードする画像(ローディング部分には関係なし) START -->
<div class="content">
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_01.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_02.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_03.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_04.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_05.jpg" alt="">
</div>
</div>
CSS
/* ローディング画面の背景 */
.loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: #fff;
/* opacityプロパティをeaseイージングで1秒かけて処理する。 */
transition: opacity 1s ease;
/*
アニメーション「change-color-loading-after」のanimationプロパティを指定。
0.3秒たった後、easeイージングで0.3秒かけてアニメーションを実行する。
bothを指定してアニメーションの実行結果をそのまま画面に残す。
*/
animation: change-color-loading-after .3s ease both .3s;
}
/*
アニメーション「change-color-loading-after」のキーフレームを指定。
背景色を操作し、はじめは真っ白で終わる頃に真っ青になる。
*/
@keyframes change-color-loading-after {
0%{
background: #fff;
}
100%{
background: #1d48bb;
}
}
/* ダミー画像用のCSS。ローディングに関係なし。 */
.image-wrap {
width: 100%;
}
.image-wrap img {
width: 100%;
height: auto;
}
/*
ローディング部分のアニメーション。
Mark JC様のCodePenを参考にさせていただきました。m(_ _)m
参考:https://codepen.io/mjcabangon/pen/pKRaZQ
*/
div.loading > div.loading-animation {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto !important;
width: 100px;
height: 100px;
}
div.loading-animation > div.loading-animation__circle {
width: 100%;
height: 100%;
margin: auto;
border: 4px solid #fff;
border-radius: 100%;
animation-fill-mode: both;
animation: loading-circle-animation 1s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8);
}
@keyframes loading-circle-animation {
0% {
transform: scale(0.1);
opacity: 1;
}
70% {
transform: scale(1);
opacity: 0.7;
}
100% {
opacity: 0.0;
}
}
JavaScript
// Webページのすべての要素が読み込まれた後に実行。
window.addEventListener('load', () => {
// sessionStorageから、
// 初回アクセスかどうかを管理する「key:loaded」の、
// 「value」の取得を試みる。
const loaded = sessionStorage.getItem('loaded');
// ローディング画面の要素を取得する。
const loading = document.getElementById('loading');
// さきほど取得した「key:loaded」が「value:null」の場合、
// 初回アクセスとみなしてif文の中身を実行する。
if (loaded === null) {
// sessionStorageに「key:loaded」を「value:true」で保存する。
// これにより、同じセッションではリロードしてもローディング画面が表示されなくなる。
sessionStorage.setItem('loaded', 'true');
// setTimeoutを1000(1秒)でセットし、
// 1秒後にローディング画面のopacityを0にする。
setTimeout(() => {
loading.style.opacity = '0';
// さらにsetTimeoutを1000(1秒)でセットし、
// 1秒後にローディング画面のdisplayをnoneにする。
setTimeout(() => {
loading.style.display = 'none';
}, 1000);
}, 1000);
// sessionStorageの「key:loaded」の「value」に
// 何らかの値が入っている場合、2回目以降のアクセスとみなして、
// すぐにローディング画面を非表示にする。
} else {
loading.style.opacity = '0';
loading.style.display = 'none';
}
});
jQuery ページローディング
jQueryの場合のコードになります。
HTML、CSSは同じです!jQueryそのものの読み込みを忘れないように気をつけてください。
HTML
<!-- ローディング部分 START -->
<div class="loading" id="loading">
<div class="loading-animation">
<div class="loading-animation__circle"></div>
</div>
</div>
<!-- ローディング部分 END -->
<!-- ロードする画像(ローディング部分には関係なし) START -->
<div class="content">
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_01.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_02.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_03.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_04.jpg" alt="">
</div>
<div class="image-wrap">
<img src="https://zenweb.info/wp-content/uploads/2023/06/progressbarjs-loading_05.jpg" alt="">
</div>
</div>
CSS
/* ローディング画面の背景 */
.loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: #fff;
/* opacityプロパティをeaseイージングで1秒かけて処理する。 */
transition: opacity 1s ease;
/*
アニメーション「change-color-loading-after」のanimationプロパティを指定。
0.3秒たった後、easeイージングで0.3秒かけてアニメーションを実行する。
bothを指定してアニメーションの実行結果をそのまま画面に残す。
*/
animation: change-color-loading-after .3s ease both .3s;
}
/*
アニメーション「change-color-loading-after」のキーフレームを指定。
背景色を操作し、はじめは真っ白で終わる頃に真っ青になる。
*/
@keyframes change-color-loading-after {
0%{
background: #fff;
}
100%{
background: #1d48bb;
}
}
/* ダミー画像用のCSS。ローディングに関係なし。 */
.image-wrap {
width: 100%;
}
.image-wrap img {
width: 100%;
height: auto;
}
/*
ローディング部分のアニメーション。
Mark JC様のCodePenを参考にさせていただきました。m(_ _)m
参考:https://codepen.io/mjcabangon/pen/pKRaZQ
*/
div.loading > div.loading-animation {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto !important;
width: 100px;
height: 100px;
}
div.loading-animation > div.loading-animation__circle {
width: 100%;
height: 100%;
margin: auto;
border: 4px solid #fff;
border-radius: 100%;
animation-fill-mode: both;
animation: loading-circle-animation 1s 0s infinite cubic-bezier(0.21, 0.53, 0.56, 0.8);
}
@keyframes loading-circle-animation {
0% {
transform: scale(0.1);
opacity: 1;
}
70% {
transform: scale(1);
opacity: 0.7;
}
100% {
opacity: 0.0;
}
}
jQuery
// Webページのすべての要素が読み込まれた後に実行。
$(window).on('load', () => {
// sessionStorageから、
// 初回アクセスかどうかを管理する「key:loaded」の、
// 「value」の取得を試みる。
const loaded = sessionStorage.getItem('loaded');
// ローディング画面の要素を取得する。
const loading = $('#loading');
// さきほど取得した「key:loaded」が「value:null」の場合、
// 初回アクセスとみなしてif文の中身を実行する。
if (loaded === null) {
// sessionStorageに「key:loaded」を「value:true」で保存する。
// これにより、同じセッションではリロードしてもローディング画面が表示されなくなる。
sessionStorage.setItem('loaded', 'true');
// delayを1000(1秒)でセットし、
// 1秒後にローディング画面がフェードアウトする。
loading.delay(1000).fadeOut(1000);
// sessionStorageの「key:loaded」の「value」に
// 何らかの値が入っている場合、2回目以降のアクセスとみなして、
// すぐにローディング画面を非表示にする。
} else {
loading.css({ 'opacity': '0', 'display': 'none' });
}
});
最後に
jQueryにはsessionStorageを利用するためのメソッドが無いのが意外でした。
今度は、プログレスバーやロードのパーセンテージが付いたタイプのローディングも作ってみようと思います!