お疲れさまです、 TAKUAN です。
今回は自身の備忘録も兼ねて無限スクロールの実装方法を書いてみました。
無限スクロールとは
Twitterなどでスクロールすると画面遷移することなく
次々と新しいコンテンツが読み込まれて出てきますよね?
(イメージ 提供:https://twitter.com/kawai_tomoya_ag)
あれです。
処理の流れ
無限スクロールは以下4つの順番で処理されます。
【画面最下部スクロール判定】
【ajaxでPHPに非同期通信】
【PHPでSQLからデータ取得】
【取得データを画面に追加】
ファイル構成
ファイル構成は、以下の通りです。
contentView.html
(表示画面)ajaxAddContent.js
(スクロール判定とコンテンツ追加)getContent.php
(SQLからコンテンツ取得)
実装
僕が実際に書いたコードを元に、実装方法をご説明します。
画面最下部スクロール判定
まず【contentView.html】
では、
コンテンツの件数を保持する要素とコンテンツが追加される要素を準備します。
<input type="hidden" id="count" value=0> <div id="content"><div>
[id="count"]
でコンテンツの件数を保持します。
[id="content"]
にはPHPから取得したコンテンツが追加されます。
次に【ajaxAddContent.js】
でスクロールの位置が画面最下部かの判定を行います。
// スクロールされた時に実行 $(window).on("scroll", function () { // スクロール位置 var document_h = $(document).height(); var window_h = $(window).height() + $(window).scrollTop(); var scroll_pos = (document_h - window_h) / document_h ; // 画面最下部にスクロールされている場合 if (scroll_pos <= 1) { // ajaxコンテンツ追加処理 ajaxAddContent() } }); // ajaxコンテンツ追加処理 function ajax_add_content() { // 追加コンテンツ var add_content = ""; // コンテンツ件数 var count = $("#count").val(); // ajax処理 $.post({ type: "post", datatype: "json", url: "getContent.php", data:{ count : count } }).done(function(data){ // コンテンツ生成 $.each(data,function(key, val){ add_content += "<div>"+val.content+"</div>"; }) // コンテンツ追加 $("#content").append(add_content); // 取得件数を加算してセット count += data.length $("#count").val(count); }).fail(function(e){ console.log(e); }) }
画面最下部にスクロールされた場合にajaxコンテンツ追加処理を実行します。
※スクロールバーが表示されていない場合はイベントが発火しないのでご注意下さい。
ajaxでPHPに非同期通信
// ajaxコンテンツ追加処理 function ajax_add_content() { // 追加コンテンツ var add_content = ""; // コンテンツ件数 var count = $("#count").val(); // ajax処理 $.post({ type: "post", datatype: "json", url: "getContent.php", data:{ count : count } }).done(function(data){ // コンテンツ生成 $.each(data,function(key, val){ add_content += "<div>"+val.content+"</div>"; }) // コンテンツ追加 $("#content").append(add_content); // 取得件数を加算してセット count += data.length $("#count").val(count); }).fail(function(e){ console.log(e); }) }
[ajax_add_content]
関数では、
コンテンツ件数をPHPに渡し、非同期通信を行います。
PHPでSQLからデータ取得
<?php header("Content-type: application/json; charset=UTF-8"); // DB接続 $pdo = new PDO(DSN, USER, PASSWORD); // コンテンツ件数 $count = $_POST["count"]; // SQL文生成 $sql = "SELECT "; $sql .= "content "; $sql .= "FROM "; $sql .= " content_table"; $sql .= "LIMIT ".$count.", ".$count + 10; // 実行結果取得 $stmt = $pdo->query($sql); // 配列取得 $content_arr = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($content_arr); exit; ?>
【getContent.php】
では、
[content_table]
テーブルから[content]
カラムを参照します。
SQL文でLIMIT句を使い[コンテンツ件数] ~ [コンテンツ件数+10]件の取得結果を[ajax_add_content]
関数に返します。
取得データを画面に追加
// ajaxコンテンツ追加処理 function ajax_add_content() { // 追加コンテンツ var add_content = ""; // コンテンツ件数 var count = $("#count").val(); // ajax処理 $.post({ type: "post", datatype: "json", url: "getContent.php", data:{ count : count } }).done(function(data){ // コンテンツ生成 $.each(data,function(key, val){ add_content += "<div>"+val.content+"</div>"; }) // コンテンツ追加 $("#content").append(add_content); // 取得件数を加算してセット count += data.length $("#count").val(count); }).fail(function(e){ console.log(e); }) }
[ajax_add_content]
関数に戻り、
【getContent.php】
の取得結果を[id="content"]
に追加します。
取得件数をコンテンツ件数に加算し、[id="count"]
に値をセットします。
<input type="hidden" id="count" value=10> <div id="content"> <div>追加されたコンテンツ1</div> <div>追加されたコンテンツ2</div> <div>追加されたコンテンツ3</div> <div>追加されたコンテンツ4</div> <div>追加されたコンテンツ5</div> <div>追加されたコンテンツ6</div> <div>追加されたコンテンツ7</div> <div>追加されたコンテンツ8</div> <div>追加されたコンテンツ9</div> <div>追加されたコンテンツ10</div> <div>
【contentView.html】
では、
[id="count"]
に取得件数を加算した値が保持されており、
[id="content"]
に取得したコンテンツが追加されます。
これで無限スクロールが完成です!!
以上、お読みいただきありがとうございました。