4

以下は、MySQL データベースのコンテンツを表示する実際のページネーション スクリプトです。ページ全体を更新するのではなく、コンテナ「#content」内にページをシームレスにロードする必要があります。何時間も広範囲に検索しましたが、このスクリプトに Ajax/JQuery を実装するのに役立つチュートリアルはありませんでした。

記事とページネーションを表示するために使用するコードは次のとおりです。

<div id="content">
<?php
include('db.php');

$stmt = $db->query('SELECT * FROM db');
$numrows = $stmt->rowCount();
$rowsperpage=21;
$totalpages=ceil($numrows/$rowsperpage);

if(isset($pageid)&&is_numeric($pageid)){$page=$pageid;}else{$page=1;} 
if($page>$totalpages){$page = $totalpages;} 
if($page<1){$page=1;}

$offset=($page-1)*$rowsperpage;

$stmt=$db->prepare("SELECT * FROM db ORDER BY ID DESC LIMIT ?,?");
$stmt->bindValue(1, "$offset", PDO::PARAM_STR);
$stmt->bindValue(2, "$rowsperpage", PDO::PARAM_STR);

if($stmt->execute()) {
while ($row = $stmt->fetch()) {
echo '

<article>
article here
</article>

';}}

$range=4;
echo'
<div id="pagination">';

if($page>1){
echo "
<a href='http://www.domain.com/1/'><<</a>";
$prevpage = $page - 1;
echo "
<a href='http://www.domain.com/$prevpage/'><</a>";
}

for ($x = ($page - $range); $x < (($page + $range) + 1); $x++) {
if(($x>0)&&($x<= $totalpages)){
if($x==$page){
echo'
<span class="current">'.$x.'</span>';
}
else{echo"<a href='http://www.domain.com/$x/'>$x</a>";}
}
}

if($page!=$totalpages){
$nextpage=$page+1;
echo"
<a href='http://www.domain.com/$nextpage/'>></a>";
echo "
<a href='http://www.domain.com/$totalpages/'>>></a>";
} 
echo '
</div>';
?>
4

2 に答える 2

3

あなたの設定は少し不明確ですが、私に我慢してください。

クライアント側では、いつ次のページをロードするか (つまり、ユーザーがボタンをクリックするか、ページの最後までスクロールするかなど) を知っていると仮定します。また、PHP コードが投稿したものは独自のファイルにあり、質問に投稿したもののみを出力します(別名、記事の HTML のみを出力し、それ以外は何も出力せず、ラッパーも何も出力しません。

あなたがしたいことは、jQuery を使用して (あなたの質問から、あなたのサイトには既にあるように見えるので、別のライブラリを追加することはあまりタブーではありません)、この PHP ページに AJAX 要求を行うことです。次に、PHP は投稿した内容をエコーアウトし、jQuery はこれを#contentdiv 内のページに挿入します。

最初の注意: PHP ページにコンテンツ div を出力させることはお勧めしません。それをクライアント側にとどめ、そのコンテンツをスクリプトが返す内容にのみ変更することをお勧めします。

新しいコンテンツをロードするには、クライアント側で次の JavaScript 関数を使用できます。

function makePaginationRequest( pagenum = 1 ) {
    // Make ajax request
    $.ajax("test2.php", {
        // Data to send to the PHP page
        data: { "pagenum": pagenum },

        // Type of data to receive (html)
        dataType: 'html',

        // What to do if we encounter a problem fetching it
        error: function(xhr, text){
            alert("Whoops! The request for new content failed");
        },

        // What to do when this completes succesfully 
        success: function(pagination) {
            $('#content').html(pagination);
        }
    })
}

サーバーに渡す必要があるその他のパラメーターは、「データ」オブジェクト内 (data: { "pagenum": pagenum },キーと値の形式) に配置できます。例からわかるように、この関数にページ番号を渡すと、「pagenum」が渡されます。サーバーに変数を要求します。

明らかに、より優れたエラー ハンドラーを実装する必要があります。また、「test2.htm」ファイル名を PHP スクリプトのファイル名に変更します。

これを行うより良い方法

私はこれについて言及せざるを得ないと感じています:

上記の方法(あなたが求めたもの)は、これを行うための本当に厄介な方法です。サーバーから AJAX データを要求するたびに、サーバーはマークアップではなくコンテンツを返す必要があります。次に、このコンテンツをクライアント側のマークアップに挿入する必要があります。

これを行うには、PHP スクリプトを変更して、最初に次のようにすべてを配列 (または複数の記事の場合は配列の配列) に配置します。

while ($row = $stmt->fetch()) {
    $output_array[] = array(
        "post_title" => $row["title"],
        "post_date" => $row["date"],
        // etc....
    );
}

次に、次のようにエコーします。

die(json_encode($output_array));

次に、json リクエストを変更します。

function makePaginationRequest( pagenum = 1 ) {
    $.ajax("test2.htm", {
        data: { "pagenum": pagenum },
        dataType: 'json',
        error: function(xhr, text){
            alert("Whoops! The request for new content failed");
        },
        success: function(pagination) {
            // Empty the content area
            $('#content').empty();

            // Insert each item
            for ( var i in pagination ) {
                var div = $('<article></article>');
                div.append('<span class="title">' + pagination[i].post_title + "</span>");
                div.append('<span class="date">' + pagination[i].post_date + "</span>");
                $('#content').append(div)
            }
        }
    })
}

jQuery は、この JSON 出力をネイティブ JavaScript オブジェクトに自動的に解析します。

クライアントにマークアップを作成させるこのアプローチを採用すると、サーバーの負荷が大幅に軽減され、必要な帯域幅が少なくなります。

考えの材料、お役に立てば幸いです。

于 2013-03-01T03:21:59.983 に答える
1

元のスクリプトの書き換えを最小限に抑えたい場合は、jQuery .load()メソッドが最善の策かもしれません。基本的にid、すべての記事を含む要素に を指定するだけで済みます。このようなものはうまくいくはずです:

<div id="container">

    <div id="articles-container">

        <article> ... </article>

    </div>

</div>   

<div id="pagination">
    <a href="some-valid-url">1</a> ...
</div>

script次に、タグといくつかの jQuery コードを追加します。

<script>

    $(function(){

        $('#pagination').on('click', 'a', function(e){

            e.preventDefault();
            var url = $(this).attr('href');
            $('#container').load(url + ' #articles-container');

        });

    });

</script>

.load()ページをフェッチし、オプションのフラグメントを URL に追加すると、フラグメントに一致する要素に結果がフィルターされます。

編集:

さて、これを現在のページネーションで機能させるには、要素を手動で交換する必要があります。したがって、生成されたマークアップが次のようになるとします。

<div id="pagination">
    <a href="/1">1</a>
    <span class="current">2</span>
    <a href="/3">3</a>
    <a href="/4">4</a>
    <a href="/5">5</a>
</div>

完了後にこれを実行したいload()ので、コールバック関数を追加する必要があります。後で必要になる、クリックされた要素への自己参照も追加しています。

$(function(){

    $('#pagination').on('click', 'a', function(e){

        e.preventDefault();
        var $this = $(this);
        var url = $this.attr('href');
        $('#container').load(url + ' #articles-container', function(response, status, jqxhr){

        });

    });

});

コールバック内で操作を開始し#paginationます。最初の部分は簡単です:

var $curr = $('#pagination span.current');
var page = $curr.text();

$curr.replaceWith('<a href="/' + page + '">' + page + '</a>');

次に、クリックしたリンクを置き換える必要があります。

$this.replaceWith('<span class="current">' + $this.text() + '</span>');

Et viola!、ページネーションを更新する必要があります。アップデート全体は次のとおりです。

$(function(){

    $('#pagination').on('click', 'a', function(e){

        e.preventDefault();
        var $this = $(this);
        var url = $this.attr('href');
        $('#container').load(url + ' #articles-container', function(response, status, jqxhr){

            var $curr = $('#pagination span.current');
            var page = $curr.text();

            $curr.replaceWith('<a href="/' + page + '">' + page + '</a>');

            $this.replaceWith('<span class="current">' + $this.text() + '</span>');
        });

    });

});
于 2013-03-01T03:43:08.873 に答える