智能分页算法

新手上路,请多包涵

我正在寻找智能分页的示例算法。所谓聪明,我的意思是我只想显示,例如,当前页面的 2 个相邻页面,因此我不会以长得离谱的页面列表结束,而是将其截断。

这是一个简单的例子,可以让它更清楚……这就是我现在所拥有的:

 Pages: 1 2 3 4 [5] 6 7 8 9 10 11

这就是我想要结束的:

 Pages: ... 3 4 [5] 6 7 ...

(在这个例子中,我只显示当前页面的 2 个相邻页面)

我在 PHP/Mysql 中实现它,并且“基本”分页(没有截断)已经编码,我只是在寻找一个优化它的例子……它可以是任何语言的例子,只要它给了我一个关于如何实施它的想法……

原文由 jeannicolas 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 324
2 个回答

这是一些基于 这个非常古老的链接 中的原始代码的代码。它使用与 Bootstrap 分页组件兼容的标记,并输出如下页面链接:

 [1] 2 3 4 5 6 ... 100
1 [2] 3 4 5 6 ... 100
...
1 2 ... 14 15 [16] 17 18 ... 100
...
1 2 ... 97 [98] 99 100
 <?php

// How many adjacent pages should be shown on each side?
$adjacents = 3;

//how many items to show per page
$limit = 5;

// if no page var is given, default to 1.
$page = (int)$_GET["page"] ?? 1;

//first item to display on this page
$start = ($page - 1) * $limit;

/* Get data. */
$data = $db
    ->query("SELECT * FROM mytable LIMIT $start, $limit")
    ->fetchAll();

$total_pages = count($data);

/* Setup page vars for display. */
$prev = $page - 1;
$next = $page + 1;
$lastpage = ceil($total_pages / $limit);
//last page minus 1
$lpm1 = $lastpage - 1;

$first_pages = "<li class='page-item'><a class='page-link' href='?page=1'>1</a></li>" .
    "<li class='page-item'><a class='page-link' href='?page=2'>2</a>";

$ellipsis = "<li class='page-item disabled'><span class='page-link'>...</span></li>";

$last_pages = "<li class='page-item'><a class='page-link' href='?page=$lpm1'>$lpm1</a></li>" .
    "<li class='page-item'><a class='page-link' href='?page=$lastpage'>$lastpage</a>";

$pagination = "<nav aria-label='page navigation'>";
$pagincation .= "<ul class='pagination'>";

//previous button

$disabled = ($page === 1) ? "disabled" : "";
$pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$prev'>« previous</a></li>";

//pages
//not enough pages to bother breaking it up
if ($lastpage < 7 + ($adjacents * 2)) {
    for ($i = 1; $i <= $lastpage; $i++) {
        $active = $i === $page ? "active" : "";
        $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
    }
} elseif($lastpage > 5 + ($adjacents * 2)) {
    //enough pages to hide some
    //close to beginning; only hide later pages
    if($page < 1 + ($adjacents * 2)) {
        for ($i = 1; $i < 4 + ($adjacents * 2); $i++) {
            $active = $i === $page ? "active" : "";
            $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
        }
        $pagination .= $ellipsis;
        $pagination .= $last_pages;
    } elseif($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
        //in middle; hide some front and some back
        $pagination .= $first_pages;
        $pagination .= $ellipsis
        for ($i = $page - $adjacents; $i <= $page + $adjacents; $i++) {
            $active = $i === $page ? "active" : "";
            $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
        }
        $pagination .= $ellipsis;
        $pagination .= $last_pages;
    } else {
        //close to end; only hide early pages
        $pagination .= $first_pages;
        $pagination .= $ellipsis;
        $pagination .= "<li class='page-item disabled'><span class='page-link'>...</span></li>";
        for ($i = $lastpage - (2 + ($adjacents * 2)); $i <= $lastpage; $i++) {
            $active = $i === $page ? "active" : "";
            $pagination .= "<li class='page-item $active'><a class='page-link' href='?page=$i'>$i</a></li>";
        }
    }
}

//next button
$disabled = ($page === $last) ? "disabled" : "";
$pagination.= "<li class='page-item $disabled'><a class='page-link' href='?page=$next'>next »</a></li>";

$pagination .= "</ul></nav>";

if($lastpage <= 1) {
    $pagination = "";
}

echo $pagination;

foreach ($data as $row) {
    // display your data
}

echo $pagination;

原文由 changelog 发布,翻译遵循 CC BY-SA 4.0 许可协议

有点晚 =),但这是我的做法:

 function Pagination($data, $limit = null, $current = null, $adjacents = null)
{
    $result = array();

    if (isset($data, $limit) === true)
    {
        $result = range(1, ceil($data / $limit));

        if (isset($current, $adjacents) === true)
        {
            if (($adjacents = floor($adjacents / 2) * 2 + 1) >= 1)
            {
                $result = array_slice($result, max(0, min(count($result) - $adjacents, intval($current) - ceil($adjacents / 2))), $adjacents);
            }
        }
    }

    return $result;
}

例子:

 $total = 1024;
$per_page = 10;
$current_page = 2;
$adjacent_links = 4;

print_r(Pagination($total, $per_page, $current_page, $adjacent_links));

输出( @键盘):

 Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)

另一个例子:

 $total = 1024;
$per_page = 10;
$current_page = 42;
$adjacent_links = 4;

print_r(Pagination($total, $per_page, $current_page, $adjacent_links));

输出( @键盘):

 Array
(
    [0] => 40
    [1] => 41
    [2] => 42
    [3] => 43
    [4] => 44
)

原文由 Alix Axel 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏