• 作成日:

【WordPress】投稿ページ(single.php)でAjax通信で無限スクロールする方法

【WordPress】投稿ページでAjax通信で無限スクロールする方法

今回はWordPressの投稿ページ(single.php)で、Ajaxを使った無限スクロールの実装方法を説明します。

前提条件は以下

  • 投稿ページ、またはカスタム投稿ページで無限スクロール
  • jQueryのAjax通信を使う
  • パーマリンクは投稿IDに設定する必要あり(後ほど説明します)

説明する環境は以下

  • macOS Catalina v10.15.5
  • Visual Studio Code v1.46.1

投稿ページでAjax通信で無限スクロールする方法

home.phpやarchive.phpなどの一覧ページではなく、single.phpの投稿ページで無限スクロールさせます。

コードは以下の記事を参考にしています。

パーマリンクを投稿IDで設定

single.phpで無限スクロールさせるときに、メインとして表示される記事を除外して、それ以外の記事を順番に表示させます。

サブループで除外の設定をするときに、表示されている記事の投稿IDを使うので、以下のようにパーマリンク設定をする必要があります。今回の構造上ではphpから投稿IDを取得できないため、JavaScriptを使って投稿IDを取得するためです。

投稿ページ(single.php)に書くこと

<?php get_header(); ?>

<main class="l-main">
  <div class="c-block">
    <div class="c-block__inner">
     
      <article class="p-article">
      <?php if ( have_posts() ) : //条件分岐:投稿があるなら ?>
      <?php while ( have_posts() ) : the_post();//繰り返し処理開始 ?>
      
       <?php endwhile; // 繰り返し終了 ?>
       <?php endif; //条件分岐終了 ?>

      </article>
     
      <div id="js-ajax"> <!-- ここに無限スクロールの記事を表示させる -->
      </div>

    </div>
  </div>
</main>

<?php get_footer();

id名js-ajaxのブロック中に無限スクロールさせる記事を表示させていきます。

JavaScriptで書くこと

init.jsというファイルを作成して以下に内容を書きます。

$(function () {
  if ($("#js-ajax").length) { /* id名js-ajaxがあれば以下を実行 */
    let documentHeight = $(document).height(); /* ページの全高さを取得 */
    let windowsHeight = $(window).height(); /* ブラウザの高さを取得 */

    let url = "http://test.com/wp-content/themes/test/ajax.php"; /* ajax.phpまでのパス */
    
    let postNumNow = 0; /* 最初に表示させる記事数 */
    let postNumAdd = 5; /* 追加する記事数 */

    let siteUrl = window.location.pathname.split("/"); /* サイトのurlを取得して、/ごとに分割 */
    let postId = siteUrl[siteUrl.length - 1]; /* 分割したurlから最後部分を取得(投稿ID) */

    let flag = false;
    $(window).on("scroll", function () {
      let scrollPosition = windowsHeight + $(window).scrollTop();

      if (scrollPosition >= documentHeight - 500) {
        if (!flag) {
          flag = true;
          $.ajax({
            type: "POST",
            url: url,
            data: {
              post_num_now: postNumNow,
              post_num_add: postNumAdd,
              post_id_add: postId,
            },
            success: function (response) {
              $("#js-ajax").append(response);
              documentHeight = $(document).height();
              postNumNow += postNumAdd;
              flag = false;
            },
          });
        }
      }
    });
  }
});

重要な部分を説明します。

ajaxファイルの読み込み(6行目)

後ほどajax.phpというファイルを作成して、その中に無限スクロールする内容を書いていきます。ajax.phpはhome.phpやsingle.phpと同じ階層に配置するので、そこまでのパスを指定しましょう。

let url = "http://test.com/wp-content/themes/test/ajax.php"; /* ajax.phpまでのパス */

表示させる記事数を指定(8、9行目)

ページが表示されたときに、最初に何記事表示させておいて、何記事ずつ表示させるのか指定します。

let postNumNow = 0; /* 最初に表示させる記事数 */
let postNumAdd = 5; /* 追加する記事数 */

投稿IDを取得する(11、12行目)

ajax.phpから投稿IDを取得できないため、サイトURLを分割して投稿IDを取得しています。

let siteUrl = window.location.pathname.split("/"); /* サイトのurlを取得して、/ごとに分割 */
let postId = siteUrl[siteUrl.length - 1]; /* 分割したurlから最後部分を取得(投稿ID) */

無限スクロールで表示させる内容を書く

無限スクロールで表示させる内容を書きます。
ajax.phpという名前でファイルを作成したら以下を書きます。ajax.phpはhome.phpやsigle.phpと同じ階層に配置します。

<?php

require_once '../../../wp-load.php'; //wordpressの関数を使うために読み込み

$offset         = isset( $_POST['post_num_now'] ) ? $_POST['post_num_now'] : 0;
$posts_per_page = isset( $_POST['post_num_add'] ) ? $_POST['post_num_add'] : 0;
$post_id_name = isset( $_POST['post_id_add'] ) ? $_POST['post_id_add'] : 0;
$post_id_array = [$post_id_name]; //投稿IDを配列化する

$args = array(

      'posts_per_page' => $posts_per_page, //何件ずつ表示させるのか
      'offset'         => $offset, //何件目から表示させるのか
      'post__not_in' => $post_id_array, //一番上にある記事は除外
      'post_type' => 'post', //投稿タイプ
      'post_status' => 'publish',//公開の記事だけ
      'has_password' => false //パスワードがある記事は除外
       );

       $the_query = new WP_Query( $args );
       if ( $the_query->have_posts() ) :
       ?>

      <?php global $previousday; 
         while ( $the_query->have_posts() ) : $the_query->the_post();
         $previousday = '';
                // -------- ここから繰り返し---------- ?>
     
      <article class="p-article">
        
      </article>

          <?php // -------- 繰り返しここまで-----------
                          endwhile; ?>

          <?php // -------- WP_query終了-----------
                          endif; ?>

    <?php wp_reset_postdata(); ?>

重要な部分を説明します。

WordPress関数を使えるようにする(3行目)

Ajax通信したファイルはWordPress関数が使えないので、wp-load.phpを最初に読み込むことで使えるようにします。

require_once '../../../wp-load.php'; //wordpressの関数を使うために読み込み

Ajax通信でデータを受け取る(5〜7行目)

init.jsで取得している以下のデータをajax.phpに渡しています。

  • 最初から表示させる記事数
  • 追加する記事数
  • 投稿ID
$offset         = isset( $_POST['post_num_now'] ) ? $_POST['post_num_now'] : 0; //最初から表示させる記事数
$posts_per_page = isset( $_POST['post_num_add'] ) ? $_POST['post_num_add'] : 0; //追加する記事数
$post_id_name = isset( $_POST['post_id_add'] ) ? $_POST['post_id_add'] : 0; //投稿ID

投稿IDを配列化する(8行目)

Ajax通信で受け取った投稿IDを配列化しています。

$post_id_array = [$post_id_name]; //投稿IDを配列化する

投稿IDを配列化する理由は、14行目のpost__not_inで記事を除外するときに配列で投稿IDを指定する必要があるからです。

'post__not_in' => $post_id_array, //一番上にある記事は除外(投稿IDを除外)

おわりに

今回はWordPressの投稿ページに、Ajax通信を使って無限スクロールする方法を紹介しました。パーマリンク設定を投稿IDで設定するなど制約がある実装方法ですが、参考にしてみてください。