PHPでAjaxを使ったCSV無限スクロール機能を作る方法【サンプルコード付き】

html/css/js

PHPでAjaxを使ったCSV無限スクロール機能を作る方法

PHPでAjaxを使ったCSV無限スクロール機能を作る方法を紹介します。Ajaxとは、ページを再読み込みせずにJavaScriptからサーバーへ通信する仕組みです。このサンプルでは、CSVファイルのデータをスクロール位置に応じて非同期で追加読み込みできます。記事一覧や商品一覧、管理画面などで大量のデータを快適に表示したい場合に利用できます。

コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

デモ

Ajax CSV無限スクロール
ID テキスト

コードをコピーして使おう!

<?php

// CSVファイル名です
$csv_file = 'data.csv';

// 1回の読み込み件数です
$limit = 20;

// CSVデータを読み込む関数です
function load_csv_data($csv_file) {

    $rows = [];

    if (!file_exists($csv_file)) {
        return $rows;
    }

    $fp = fopen($csv_file, 'r');

    if ($fp) {

        // 1行目の見出しを読み飛ばします
        fgetcsv($fp);

        while (($data = fgetcsv($fp)) !== false) {

            if (count($data) >= 2) {
                $rows[] = [
                    'id' => $data[0],
                    'text' => $data[1]
                ];
            }

        }

        fclose($fp);
    }

    return $rows;
}

// Ajax通信でoffsetが送られた場合の処理です
if (
    $_SERVER['REQUEST_METHOD'] === 'POST' &&
    isset($_POST['offset'])
) {

    $offset = (int)$_POST['offset'];

    if ($offset < 0) {
        $offset = 0;
    }

    $rows = load_csv_data($csv_file);

    // 指定位置から20件だけ取得します
    $items = array_slice($rows, $offset, $limit);

    header('Content-Type: application/json; charset=UTF-8');

    echo json_encode([
        'rows' => $items,
        'next_offset' => $offset + $limit,
        'has_more' => ($offset + $limit) < count($rows)
    ], JSON_UNESCAPED_UNICODE);

    exit;
}

?>

<!DOCTYPE html>
<html lang="ja">
<head>

<meta charset="UTF-8">

<title>Ajax CSV無限スクロール</title>

<style>
body{
    font-family:sans-serif;
    background:#f8fafc;
    margin:40px;
}

.php-ajax-csv-infinite-scroll_wrap{
    max-width:700px;
    height:520px;
    overflow-y:auto;
    margin:0 auto;
    padding:24px;
    border:1px solid #e5e7eb;
    border-radius:18px;
    background:#ffffff;
}

.php-ajax-csv-infinite-scroll_title{
    font-size:22px;
    font-weight:bold;
    margin-bottom:20px;
}

.php-ajax-csv-infinite-scroll_table{
    width:100%;
    border-collapse:collapse;
}

.php-ajax-csv-infinite-scroll_table th,
.php-ajax-csv-infinite-scroll_table td{
    border:1px solid #d1d5db;
    padding:10px;
    text-align:left;
}

.php-ajax-csv-infinite-scroll_table th{
    background:#f1f5f9;
    position:sticky;
    top:0;
}

.php-ajax-csv-infinite-scroll_status{
    margin-top:20px;
    text-align:center;
    color:#2563eb;
    font-weight:bold;
}
</style>

</head>
<body>

<div id="scrollArea" class="php-ajax-csv-infinite-scroll_wrap">

    <div class="php-ajax-csv-infinite-scroll_title">
        Ajax CSV無限スクロール
    </div>

    <table class="php-ajax-csv-infinite-scroll_table">

        <thead>
            <tr>
                <th>ID</th>
                <th>テキスト</th>
            </tr>
        </thead>

        <tbody id="dataBody"></tbody>

    </table>

    <div
        id="status"
        class="php-ajax-csv-infinite-scroll_status"
    ></div>

</div>

<script>

let offset=0;
let loading=false;
let hasMore=true;

// CSVデータをAjaxで追加読み込みします
function loadMore(){

    if(loading || !hasMore){
        return;
    }

    loading=true;

    document.getElementById('status').textContent='読み込み中...';

    fetch(location.href,{

        method:'POST',

        headers:{
            'Content-Type':'application/x-www-form-urlencoded'
        },

        body:new URLSearchParams({
            offset:offset
        })

    })

    .then(response=>response.json())

    .then(data=>{

        const body=document.getElementById('dataBody');

        data.rows.forEach(function(row){

            body.insertAdjacentHTML(
                'beforeend',
                '<tr><td>' + row.id + '</td><td>' + row.text + '</td></tr>'
            );

        });

        offset=data.next_offset;
        hasMore=data.has_more;

        if(hasMore){
            document.getElementById('status').textContent='下までスクロールすると続きを読み込みます。';
        }else{
            document.getElementById('status').textContent='すべてのデータを読み込みました。';
        }

        loading=false;

    });

}

// 初期表示で最初のデータを読み込みます
loadMore();

// スクロール位置が下に近づいたら続きを読み込みます
document.getElementById('scrollArea').addEventListener('scroll',function(){

    if(
        this.scrollTop + this.clientHeight >= this.scrollHeight - 20
    ){
        loadMore();
    }

});

</script>

</body>
</html>

ファイル構成と設置方法

このサンプルでは、index.phpdata.csv を同じフォルダに配置して使用します。CSVファイルのデータはAjax通信で少しずつ取得され、スクロール位置に応じて一覧へ自動で追加表示されます。

sample/
├── index.php
└── data.csv
  

index.phpdata.csv を同じフォルダへ配置し、ブラウザから index.php にアクセスしてください。初回表示時は先頭20件が表示され、その後スクロールして下端付近まで移動すると、Ajax通信によって次の20件が自動で読み込まれます。これを繰り返すことで、ページを切り替えることなくCSVデータを順次表示できます。


コメント