シングルページの記事詳細を無限スクロールさせる

構築・開発WordPress

詳細記事をページスクロールし、一番下まで行くと自動的に次の記事を表示させる方法です。
今回は、ただロードしてくるだけでなく、該当記事の位置に行くとアドレスバーにあるURLも書き換える仕様になります。

下記のサイトを参考に2パターン挑戦してみたのですが、そもそもの作りが悪いからなのか、どちらも意図した動きになりませんでした。

 

そこで、今回は、jquery.autopager というものを使用することにしました。
かなり古くからあるプラグインで、公式?のものは既にサイトがなくなっているのですが、GitHubにForkされたものがあります。

GitHub – sagotsky/jquery-autopager

使い方

<div id="contents">
    <div class="article" data-url="<?php echo get_permalink() ?>">
        ・・・タイトルや本文など・・・
    </div>
    
<?php
    $preview_post = get_previous_post(); 
    if (!empty( $preview_post )){
        echo '<div id="autoload"><a href="'.get_permalink( $preview_post->ID ).'">読み込み中...</a></div>'; 
    }
?>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/jquery.autopager-1.0.0.js"></script>
<script>
    $(function(){
        $.autopager({
            autoLoad: true,
            content : '.article',
            link : '#autoload a',
            load: function(current, next){
                //読み込む記事リンクがない場合、要素を非表示に
                if(next['url'] == undefined){
                    $('#autoload').css('display', 'none');
                }
            }
        });
    });
</script>

これだけで、自動読込機能は動くと思います。
URLの書き換えも、新しい記事を読み込んだ際に書き換わっていると思いますが、ページの上部にスクロールして、前の記事に戻った際は、URLが書き換わることはありません。
なぜなら、このプラグインでは読み込む時にのみアドレスの書き換え処理が動きます。

そこで、コンテンツ位置によって、アドレス書き換え部分は別実装する必要があります。

<script>
    $(function(){
        var timer = null;
        var c = {};
        $(window).on('scroll',function() {
            clearTimeout( timer );
            
            //スクロール時、リアルタイムではなく、処理を少し遅延させる
            timer = setTimeout(function() {
                var doc_top = $(document).scrollTop();
                var doc_bottom = doc_top + window.innerHeight;
                
                //記事の位置を設定
                $('.article').each(function(i, e){
                    var content_top = $(this).offset().top;
                    var content_bottom = content_top + $(this).innerHeight();
                    var content_url = $(this).attr('data-url');
                    
                    if(
                        ((content_top + 80 < doc_bottom && doc_top < content_top)
                            || (content_bottom + 80 > doc_bottom && content_top < doc_top))
                        && (location.href !== content_url)
                    ){
                        //読込済みの記事に表示部分が替わった時にアドレスバーのリンクを書き換える
                        window.history.replaceState(null, null, content_url);
                        return false;
                    }
                });
            }, 200 );
        });
    });
</script>

これで、上下スクロールしても該当記事の所のアドレスになるかと思います。

注意

前記事を取得する get_previous_post() で取得記事が異なる場合、この関数を使う前に WP_Queryなどで詳細ページのクエリ情報を書き換えていないか確認してください。
書き換えていた場合、wp_reset_query() で、リセットしていても順番通りになりませんでした。

そこで、

<?php if(have_posts()): while(have_posts()): the_post(); ?>
<?php endwhile; endif; ?>

で、囲ってあげれば、正常な順序となります。

<?php
    if(have_posts()): while(have_posts()): the_post();
        $preview_post = get_previous_post(); 
        if (!empty( $preview_post )){
            echo '<div id="autoload"><a href="'.get_permalink( $preview_post->ID ).'">読み込み中...</a></div>'; 
        }
    endwhile; endif;
?>

 

コメント

スポンサーリンク
タイトルとURLをコピーしました