WordPressで無限スクロールをやってみる

コンテンツの一覧を表示する手法としてすっかり定着した「無限スクロール」を、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: ページの読み込みの状態を示すステータス要素を指定します。

オプションやイベントの詳細は、「Infinite Scroll」のサイトにあります。

投稿一覧ページにステイタス表示の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」プラグインは、割と思い通りにカスタマイズできるので、テーマごとの違いに対応できていいと思いました。

ただ、サイトに無限スクロールを導入するかどうかの判断は悩む所です。

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です。