最近ブログなどでよく使われている機能として、もっと見る形式のページングがあります。
「もっと見る」を押すといくつかの記事コンテンツが下に追加されるタイプのものです。
(記事本文の冒頭を少しだけ表示させておき、「もっと見る」を押すと全文が表示されるタイプではありません。)
こういった「もっと見る」ボタンはそのままだと不便な点があります。
記事一覧ページで「もっと見る」を押していくつか記事コンテンツを表示させた後、
読みたい記事をクリックし、記事を読んで、一覧に戻ってきた際・・・
一番上まで戻ってしまった、そんな経験はありませんか?
改良前
つまりこういうことです。
ページ3の黄色ゾーンにいたのに、ページ1の青色ゾーンまで戻ってしまっていますね・・・。
GIFが表示されない方はこちらから
改良後
ページ2とページ3の間の中途半端な位置にいたのに、ちゃんと戻って来れています!
GIFが表示されない方はこちらから
実装の前に用語解説
今回はsessionStorageというものを使います。
SessionStorageとはWebStorageの一種で、javascriptを用いてクライアント側にデータを保存する仕組みです。ユーザのローカルへデータを保存することができるのはLocalStorageと同じですが、データの有効期限が異なります。LocalStorageでは半永久的にデータを保持できるのに対し、SessionStorageはウィンドウやタブを閉じるまでしか保持できません。そのため、サーバで使われるセッションと同じように、作業途中のデータや画面遷移時の一時的なデータ保存などに有効活用できます。
出典 Webエンジニアのブログ
データベースとの連携が必要ないのは、フロントエンドエンジニアに優しいですね!
解説
JavaScriptの中身を見ていきましょう。
「もっと見る」を押すと、ページ数に応じてクエリパラメータがつく
設計
1.「もっと見る」ボタンを押す
2.次のページが下に追加される
3.次のページの部分までスクロールする
4.URLにクエリパラメータを追加する
5.前のページの「もっと見る」ボタンを隠す
コード
const pathname = window.location.pathname;
const SPEED = 600;
//ボタンを押した際に次のページが表示される
$('#btn_page1').on('click', () => {
$('#page2').slideDown();
$("html, body").animate({ scrollTop: $('#page2').offset().top }, SPEED, "swing");
history.replaceState('', '', pathname + '?p=2');
$('#btn_page1').hide();
return false;
});
$('#btn_page2').on('click', () => {
$('#page3').slideDown();
$("html, body").animate({ scrollTop: $('#page3').offset().top }, SPEED, "swing");
history.replaceState('', '', pathname + '?p=3');
$('#btn_page2').hide();
return false;
});
$('#btn_page3').on('click', () => {
$('#page4').slideDown();
$("html, body").animate({ scrollTop: $('#page4').offset().top }, SPEED, "swing");
history.replaceState('', '', pathname + '?p=4');
$('#btn_page3').hide();
return false;
});
クエリパラメータとは、URLの横につく?p=2
や?p=3
の部分です。
完成品のデモでURL部分に注目して見ていただいたら分かるかと思います。
外部リンクに飛ぶと、スクロール位置がsessionStorageに記録される
設計
1.外部リンクをクリックする
2.スクロール量をsessionStorageに記録
コード
//スクロール位置をsessionStorageに記録
$('a.external-link').click(function () {
sessionStorage['scrollTopStocked'] = $(window).scrollTop();
});
外部リンクのaタグにはexternal-linkというクラス名をつけています。
戻ってきたとき、クエリパラメータに応じてページが開き、スクロール位置も戻る
設計
1.クエリパラメータが2のとき、2ページ目を表示し1ページ目のボタンを非表示にする
2.クエリパラメータが3のとき、3ページ目を表示し1,2ページ目のボタンを非表示にする
3.クエリパラメータが4のとき、4ページ目を表示し1,2,3ページ目のボタンを非表示にする
4.クエリパラメータがないときはsessionStorageのデータを削除する
5.sessionStorageに記録していた値の分だけスクロールする
コード
/**
* クエリパラメータ
*/
const queryParam = location.search;
/**
* クエリパラメータから取得したページ番号
*/
const pageNumberByQuery = queryParam.split('?p=')[1];
//クエリパラメータがある時のみ実行
if (pageNumberByQuery) {
//クエリパラメータから取得したページ番号の値に応じて、ページを開く
switch (pageNumberByQuery) {
case '2':
$('#page2').show();
$('#btn_page1').hide();
break;
case '3':
$('#page2').show();
$('#btn_page1').hide();
$('#page3').show();
$('#btn_page2').hide();
break;
case '4':
$('#page2').show();
$('#btn_page1').hide();
$('#page3').show();
$('#btn_page2').hide();
$('#page4').show();
$('#btn_page3').hide();
break;
default:
break;
}
} else {
//sessionStorageの値を破棄
sessionStorage.removeItem('scrollTopStocked‘);
}
const scrollTopBySessionStorage = sessionStorage.getItem('scrollTopStocked');
if (scrollTopBySessionStorage) {
$(window).scrollTop(scrollTopBySessionStorage);
}
location.searchでURLのクエリパラメータを取得したあと、splitで分割し、ページ番号のみ取得します。
おわりに
以上、もっと見るボタンの改善についての提案でした。
本記事のデモは、静的ページとして作ったサンプルです。
なのでWordPressのような動的ページで実装する場合は、実際に書くコードは異なります。
しかし同様の考え方で実装が可能です。参考にしてみてください!
この「もっと見る」ボタンを使って、当ブログを改修する話が進んでいるとかいないとか・・・?
ロジカルスタジオの採用についての「もっと見る」ボタンはこちら↓