ajaxっぽいスムーズな画面遷移の方法(3/3)

Tips

全3回でご紹介の、「ajaxっぽい画面遷移」
少し時間が空いてしまいましたが今回が完結編となります。
第2回は実践編として
リンクの通常の挙動をストップ→ローディングを表示→ページ遷移という
前半の処理の基本的な流れを説明しました。
実践編の後半の今回は、

  1. 「imagesLoaded」を使って簡単にプログレスバーのあるローディング画面を実装する
  2. window.onpageshowを使用し、ブラウザバックを検知してローディング画面を隠す

という流れで説明したいと思います。

1. 「imagesLoaded」を使って簡単にプログレスバーのあるローディング画面を実装する

前回の処理で無事、同じ見た目の画面へのページ遷移をし
「ajaxっぽい画面遷移」の前半部分ができましたが、
この後、画像の表示されていない状態でロード画面が開けてしまっては
格好がつかないので、画像のロードを待ってから
ロード画面を開けるという処理を行いたいと思います。
イメージのロード完了を手動で検知させるということもできますが、
ここでは便利なライブラリの「imagesLoaded」を使いたいと思います。
使い方は簡単で、
公式ページから、ダウンロードするか、CDNでjsファイルを読み込んで使います。
jQueryを使用する場合は
$('#container').imagesLoaded( function() { /* 画像読み込み後の処理 */ });の形で、
指定の要素に含まれる画像を読み込んだあとにさせたい処理を書くだけです。
画像のローディングに対して簡単なプログレスバーも実装したいので、
imagesLoadedのprogressというメソッドも使ってみたいと思います。


<div id="loading"><span>LOADING</span>
<div id="bar"></div>
</div>

#loading {
background-color: #f0f0f0;
position: fixed;
top: 0%;
left: 0;
width: 100%;
height: 100%;
z-index: 10000;
transition: ease .5s;
}
#loading.is-hidden {
opacity: 0;
top: -100%;
}
#loading span {
font-family: sans-serif;
display: block;
text-align: center;
width: 100%;
height: 40px;
color: #ccc;
font-size: 16px;
letter-spacing: 4px;
text-indent: -4px;
position: absolute;
top: calc( 50% - 10px );
left: 0;
}
/* ローディング画面の下端にプログレスバーを表示 */
#loading #bar {
position: absolute;
display:block;
height: 6px;
width: 0%;
bottom: 0;
left: 0;
background-color: rgba(255, 96, 96, 1);
transition: ease .1s;
}
#loading #bar.hide {
opacity: 0;
}
$(function(){
var loading = $('#loading');
var links = $('a.movepage');
var bar = $('#bar');
links.on('click',function(event){
// クリック時に発生するイベントをキャンセル
event.preventDefault();
// ローディング画面を表示
loading.removeClass('is-hidden');
// 移動先のURLを取得して指定秒数後にページ遷移する
var href = $(this).attr('href'), // クリックしたリンクから遷移先URLを取得
wait = 500; // 待ち時間をミリ秒で指定
setTimeout(function(){
// ページ遷移の処理
location.href = href ;
}, wait);
});
// #content内の画像のロード時に下の関数を実行
$('#content').imagesLoaded()
.progress( advanceLoading )
.done( hideLoading );
function advanceLoading(e){
// プログレスバーを進める
var length = e.images.length, // 画像の枚数
count = e.progressedCount, // 読み込み完了した枚数
progress =  ( count / length ) * 100; // パーセントの値に
bar.width( progress + '%' );
if( progress == 100 ){
// 100%になったらバーを隠す
bar.addClass('is-hidden');
}
}
function hideLoading(){
// ローディング完了のタイミングでローディング画面を隠す
loading.addClass('is-hidden');
}
});

上記では、画像の枚数に対してローディング完了した枚数を
imagesLoadedのメソッドから取得し、
それを%に直して#barのwidthを変更して
プログレスバーを実装しています。
また、ローディング完了時に実行されるdoneメソッドを使って、
ローディング完了時にローディング画面を隠すための処理(クラスをつけるだけですが)
を実行しています。

2. window.onpageshowを使用し、ブラウザバックを検知してローディング画面を隠す

さて、これでajaxっぽい動きを実装するための一通りの処理はできたのですが、
safari等で表示したとき、このままブラウザバックをすると、
ローディング画面が出た状態の画面に遷移してしまいます、
これはブラウザの仕様でブラウザバックをすると、
キャッシュしてあるページを読みに行ってリロードしないために起こる現象のようで、
※bfcache( Back-Forward Cache ) というらしいです。
通常の場合はこのお陰でブラウジングが快適になるようなのですが、
今回の処理ではこの機能のお陰でページが見えない状態になってしまいます。
そこで、pageshowというイベントと、
初回ロード時にはfalseがセットされるpersistedというプロパティを
利用して下記の処理を追加し、
ブラウザバックで戻った場合にはローディング画面を隠す処理をさせます。

$(function(){
var loading = $('#loading');
var links = $('a.movepage');
var bar = $('#bar');
links.on('click',function(event){
// クリック時に発生するイベントをキャンセル
event.preventDefault();
// ローディング画面を表示
loading.removeClass('is-hidden');
// 移動先のURLを取得して指定秒数後にページ遷移する
var href = $(this).attr('href'), // クリックしたリンクから遷移先URLを取得
wait = 500; // 待ち時間をミリ秒で指定
setTimeout(function(){
// ページ遷移の処理
location.href = href ;
}, wait);
});
// #content内の画像のロードのに対して下の関数を実行
$('#content').imagesLoaded()
.progress( advanceLoading )
.done( hideLoading )
function advanceLoading(e){
// プログレスバーを進める
var length = e.images.length, // 画像の枚数
count = e.progressedCount, // 読み込み完了した枚数
progress =  ( count / length ) * 100; // パーセントの値に
bar.width( progress + '%' );
if( progress == 100 ){
// 100%になったらバーを隠す
bar.addClass('is-hidden');
}
}
function hideLoading(){
// ローディング完了のタイミングでローディング画面を隠す
loading.addClass('is-hidden');
}
// ブラウザバック時のローディング画面対策
window.onpageshow = function(e) {
if( e.persisted == true ){
// ローディング画面を隠す
hideLoading();
/* もしローディング画面を出す以外にも画面遷移時に処理を行っている場合など、
* 何らかの不具合が出た場合には、
* 画面を読み込み直すのでブラウジングのスムーズさが少し損なわれてしまいますが、
* 強制的にリロードさせる下記の処理をさせると大体解決します。*/
// window.location.reload();
}
}
});

全3回に渡って書いてきました、
「ajaxっぽい画面遷移」の実装方法もこれでおしまいです。
もし「リッチなWEBサイトを作りたいけど、あまり工数がかけられない!」という
フロントエンドの皆さまのお役に立てば幸いです!
それでは、今年はこれでブログ納となりますが、
来年もどうぞよろしくお願いいたします。
皆さま良いお年を!

お問い合わせ

    個人情報利用目的への同意

    ※このサイトはCloudflare Turnstileよって保護されています。
    ※お客様が入力した個人情報はSSL暗号化信号によって保護されています。

    個人情報の利用目的
    このお問い合わせフォームでご提供いただく個人情報は、お問合せ等に対する回答や資料送付、その他ご連絡のために利用します。
    当個人情報を第三者に提供することはありません。
    当個人情報の取扱いを委託することはありません。
    必要事項を全てご入力下さい。入力内容に不備がある場合は、ご返信しかねる場合がございます。
    内容により、お時間をいただく場合がございます。
    当個人情報の利用目的の通知、開示、内容の訂正・追加または削除、利用の停止・消去および第三者への提供の停止(「開示等」といいます。)を受け付けております。
    開示等の求めは、info@commono.co.jpで受け付けます。
    統計ツールやクッキー、ウェブビーコン等を用いてご利用状況を調査していますが、これによる個人情報の取得、利用は行っておりません。
    当社の個人情報保護に対する取り組みは「Privacy Policy」を必ずご確認ください。

    COMMONO株式会社
    E-mail:info@commono.co.jp
    個人情報保護方針、個人情報の取扱いについて
    PRIVACY POLICY

    現在準備中です

    お気に入り

    お気に入りから削除

    選択したアイテムをお気に入りから削除しますか?