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 回答