コンテンツの一覧を表示する手法としてすっかり定着した「無限スクロール」を、WordPressで遅ればせながらやってみようと思います。
一から作るのは面倒なので、「Infinite Scroll」というJsプラグインを使います。
このプラグインはWordPress専用ではないので、テーマのカスタマイズが必要になりますが、オプションなども充実しているので便利です。
今回は一般的なテーマの投稿一覧ページを、無限スクロールにする想定でやっていきます。
目次
子テーマを作成
今回は、公式テーマの「Twenty Twenty」に実装してみます。
直接テーマをいじるのは良くないので、子テーマを作成してカスタマイズしていきます。
WordPressの「wp-content」-「themes」のディレクトリ内に twentytwenty-child という名前で新規ディレクトリを作成します。
その中に style.css と functions.php の2つのファイルを作成して入れます。
例: style.css
/*
Theme Name: Twenty Twenty Child
Description: Twenty Twenty Child Theme
Template: twentytwenty
Version: 1.0.0
Text Domain: twentytwenty-child
*/
例: functions.php
<?php
/* ScriptとStyleの読み込み */
function twentytwenty_child_scripts() {
// 親テーマのスタイルの読み込み
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
}
add_action( 'wp_enqueue_scripts', 'twentytwenty_child_scripts' );
infinite-scroll.js ファイルを作成して読み込む
「Infinite Scroll」のサイトから、「infinite-scroll.pkgd.min.js」か「infinite-scroll.pkgd.js」をコピペして infinite-scroll.js などの名前を付けて、twentytwenty-child ディレクトリ内に置きます。
そのファイルを読み込む設定を functions.php に記述します。
例: functions.php
<?php
/* ScriptとStyleの読み込み */
function twentytwenty_child_scripts() {
// 親テーマのスタイルの読み込み
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
// infinite-scroll.js の読み込み
wp_register_script( 'infinite-scroll', get_stylesheet_directory_uri() . '/infinite-scroll.js', array( 'jquery' ), false, true );
if ( is_home() ) {
wp_enqueue_script( 'infinite-scroll' );
}
}
add_action( 'wp_enqueue_scripts', 'twentytwenty_child_scripts' );
is_home() の条件分岐タグで、投稿一覧ページだけで読み込むようにしています。
infinite-scroll.js に初期化の設定を追加する
twentytwenty-child ディレクトリ内に置いた infinite-scroll.js ファイルに初期化の設定を追記します。
今回は、jQueryを使用することにします。
例: 初期化の設定
jQuery(function($) {
// 次ページに行くリンクをチェック
const nextLink = $('#site-content .nav-links a.next').length;
// 初期化
if (nextLink) {
$('#site-content').infiniteScroll({
append: 'article.post',
path: '.nav-links a.next',
hideNav: '.nav-links',
scrollThreshold: 100,
status: '.scroller-status'
});
// Twenty Twentyの場合は、hr要素も追加する
$('#site-content').on('append.infiniteScroll', function(event, response, path, items) {
for (const ele of items) {
$('#' + ele.id).after('<hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" />');
}
});
}
});
次ページに行くリンクの有無をチェックして、無い場合には初期化しないようにしておきます。
$(〜).infiniteScroll() の「〜」の部分は、記事一覧のアイテムを包む要素を指定します。
「Twenty Twenty」は、読み込むアイテムに hr要素もあるので、イベントを利用して追加しています。
Options
append: 記事一覧のアイテム要素を指定します。
path: 次ページに行くリンク要素を指定します。
hideNav: 非表示にしたいナビゲーション要素を指定します。
scrollThreshold: スクロール領域までの距離(px)を指定します。
status: ページの読み込みの状態を示すステータス要素を指定します。
投稿一覧ページにステイタス表示のHTMLを記述する
投稿一覧ページを表示させているテンプレートファイルを調べて、親テーマから子テーマの twentytwenty-child ディレクトリ内にコピーします。
そこに、ステイタス情報を表示させるHTMLを記述します。
「Twenty Twenty」の場合は、index.phpです。
例: index.php
<!-- 前略 -->
<?php get_template_part( 'template-parts/pagination' ); ?>
</main><!-- #site-content -->
<!-- ここから -->
<div class="scroller-status">
<p class="infinite-scroll-request">ロード中...</p>
<p class="infinite-scroll-last">これ以上は記事がありません</p>
<p class="infinite-scroll-error">記事が読み込めません</p>
</div>
<!-- / ここまで -->
<?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>
<!-- 後略 -->
<div class=”scroller-status”>の部分のクラス名は、オプションの「status」に指定します。
Status
.infinite-scroll-request: ロード中に表示されます。
.infinite-scroll-last: 最後のページに表示されます。
.infinite-scroll-error: 次のページを読み込めなかったときに表示されます。
例: style.css
.scroller-status {
display: none;
}
style.css に追記して、最初にステイタス表示を消しておきます。
もっとみるボタンにする場合
以上で、無限スクロールは実装できますが、
WordPressで利用されている一般的なテーマはフッター部分があるのがほとんどです。それだと、スクロールが終わるまでフッター部分が現れないことになります。
そこで、もっとみるボタンを設置して読み込む方法もやってみます。
※ついでにローダー画像とかも表示させてみます。
例: index.php
<!-- 前略 -->
<?php get_template_part( 'template-parts/pagination' ); ?>
</main><!-- #site-content -->
<!-- ここから -->
<div class="scroller-status">
<div class="infinite-scroll-request"><div class="spinner"></div></div>
<p class="infinite-scroll-last">これ以上は記事がありません</p>
<p class="infinite-scroll-error">記事が読み込めません</p>
</div>
<div><button class="view-more-btn" type="button">もっとみる</button></div>
<!-- / ここまで -->
<?php get_template_part( 'template-parts/footer-menus-widgets' ); ?>
<!-- 後略 -->
<button class=”view-more-btn” type=”button”>の部分のクラス名は、オプションの「button」に指定します。
「.infinite-scroll-request」 にローダー画像用のHTMLを記述します。
例: infinite-scroll.js
jQuery(function($) {
// 次ページに行くリンクをチェック
const nextLink = $('#site-content .nav-links a.next').length;
// 初期化
if (nextLink) {
$('#site-content').infiniteScroll({
append: 'article.post',
path: '.nav-links a.next',
hideNav: '.nav-links',
button: '.view-more-btn',
scrollThreshold: false,
status: '.scroller-status'
});
// Twenty Twentyの場合は、hr要素も追加する
$('#site-content').on('append.infiniteScroll', function( event, response, path, items) {
for (const ele of items) {
$('#' + ele.id).after('<hr class="post-separator styled-separator is-style-wide section-inner" aria-hidden="true" />');
}
});
} else {
$('.view-more-btn').css('display', 'none'); // 不要なとき消す
}
});
オプションの「button」に button要素のクラス名を指定して、「scrollThreshold」を false にします。
例: style.css
.scroller-status {
display: none;
text-align: center;
}
.view-more-btn {
display: block;
margin: 0 auto;
}
/* ローダー画像 https://tobiasahlin.com/spinkit/ */
.spinner {
width: 40px;
height: 40px;
margin: 100px auto;
background-color: #333;
border-radius: 100%;
-webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
animation: sk-scaleout 1.0s infinite ease-in-out;
}
@-webkit-keyframes sk-scaleout {
0% { -webkit-transform: scale(0) }
100% {
-webkit-transform: scale(1.0);
opacity: 0;
}
}
@keyframes sk-scaleout {
0% {
-webkit-transform: scale(0);
transform: scale(0);
} 100% {
-webkit-transform: scale(1.0);
transform: scale(1.0);
opacity: 0;
}
}
適当なスタイルを指定して完成です。
まとめ
今回の「Infinite Scroll」プラグインは、割と思い通りにカスタマイズできるので、テーマごとの違いに対応できていいと思いました。
ただ、サイトに無限スクロールを導入するかどうかの判断は悩む所です。