thinkphp6框架ajax加载数据列表专用的数字分页自定义封装类

实现效果

1、封装类部分:<项目根目录>/extend/lib/Paginator.php

<?php
namespace lib;

class Paginator
{
    //总记录
    private $total;
    //每页显示多少条
    private $limit;
    //当前页码
    private $page;
    //总页码
    private $pcount;
    //分页步长
    private $both;
    /**
     * 构造
     */
    public function __construct($total, $limit = 10, $both = 2)
    {
        if (!('integer' === gettype($total) && $total)) {
            $total = 0;
        }
        if (!('integer' === gettype($limit) && $limit)) {
            $limit = 10;
        }
        if (!('integer' === gettype($both) && $both)) {
            $limit = 2;
        }
        $this->total = $total;
        $this->limit = $limit;
        $this->both = $both;
        $this->pcount = ceil($this->total / $this->limit);
        $this->page = $this->picker();
        if ($this->page >= $this->pcount) {
            $this->page = $this->pcount;
        }
    }
    /*
     * 生成分页
     * mode参数说明:0-完整输出;1-仅输出数字分页;2-输出数字+前后;3-输出数字+首尾
     */
    public function build($mode = 0)
    {
        $out = '';
        if (!('integer' === gettype($mode) && in_array($mode, array(0, 1, 2, 3)))) {
            $mode = 0;
        }
        if (in_array($mode, array(0, 3))) {
            $out .= $this->first();
        }
        if (in_array($mode, array(0, 2))) {
            $out .= $this->prev();
        }
        $out .= $this->plist();
        if (in_array($mode, array(0, 2))) {
            $out .= $this->next();
        }
        if (in_array($mode, array(0, 3))) {
            $out .= $this->last();
        }
        return $out;
    }
    /*
     * 当前页码拾取器
     */
    private function picker()
    {
        $page = isset($_POST['page']) ? $this->format($_POST['page']) : 0;
        if (!$page) {
            return 1;
        }
        if ($page > $this->pcount) {
            $page = $this->pcount;
        }
        return $page;
    }
    /*
     * 数字格式化
     */
    private function format($num)
    {
        $type = gettype($num);
        if ('boolean' === $type) {
            return $num ? 1 : 0;
        } elseif (in_array($type, array('integer', 'string'))) {
            return preg_match('/^[0-9]+$/', $num) ? (int) $num : 0;
        } else {
            return 0;
        }
    }
    /*
     * 数字页码
     */
    private function plist()
    {
        $out = '';
        for ($i = $this->both; $i >= 1; $i--) {
            $page = $this->page - $i;
            if ($page < 1) {
                continue;
            }
            $out .= '<a data-page-num="' . $page . '" href="javascript:;">' . $page . '</a>';
        }
        $out .= '<a href="javascript:;" class="cur">' . $this->page . '</a>';
        for ($i = 1; $i <= $this->both; $i++) {
            $page = $this->page + $i;
            if ($page > $this->pcount) {
                break;
            }
            $out .= '<a data-page-num="' . $page . '" href="javascript:;">' . $page . '</a>';
        }
        return $out;
    }
    /*
     * 首页
     */
    private function first()
    {
        $dist = $this->both + 1;
        if ($this->page > $dist) {
            $out = '<a data-page-num="1" href="javascript:;" class="flex-ac icon icon-first"></a>';
            return $out;
        }
    }
    /*
     * 上一页
     */
    private function prev()
    {
        if ($this->page == 1) {
            return '';
        }
        $page = $this->page - 1;
        $skip = $this->page - ($this->both * 2) - 1;
        $out = '<a data-page-num="' . $page . '" href="javascript:;"';
        $out .= ' class="flex-ac icon icon-prev"></a>';
        if ($skip > 0) {
            $out .= '<a data-page-num="' . $skip . '"';
            $out .= ' href="javascript:;">…</a>';
        }
        return $out;
    }
    /*
     * 下一页
     */
    private function next()
    {
        if ($this->page == $this->pcount) {
            return '';
        }
        $out = '';
        $page = $this->page + 1;
        $skip = $this->page + ($this->both * 2) + 1;
        if ($skip < $this->pcount) {
            $out .= '<a data-page-num="' . $skip . '"';
            $out .= ' href="javascript:;">…</a>';
        }
        $out .= '<a data-page-num="' . $page . '" href="javascript:;"';
        $out .= ' class="flex-ac icon icon-next"></a>';
        return $out;
    }
    /*
     * 尾页
     */
    private function last()
    {
        $dist = $this->pcount - $this->page;
        if ($dist > $this->both) {
            $out = '<a data-page-num="' . $this->pcount . '" href="javascript:;"';
            $out .= ' class="flex-ac icon icon-last"></a>';
            return $out;
        }
    }
}

调用示例

$paginator = new Paginator(10000);
$paginate = $paginator->build();

输出html

<div class="flex-ac pages">
  <a data-page-num="" href="javascript:;" class="flex-ac icon icon-first"></a>
  <a data-page-num="" href="javascript:;" class="flex-ac icon icon-prev"></a>
  <a data-page-num="" href="javascript:;">...</a>
  <a data-page-num="" href="javascript:;">4</a>
  <a data-page-num="" href="javascript:;">5</a>
  <a data-page-num="" href="javascript:;" class="cur">6</a>
  <a data-page-num="" href="javascript:;">7</a>
  <a data-page-num="" href="javascript:;">8</a>
  <a data-page-num="" href="javascript:;">...</a>
  <a data-page-num="" href="javascript:;" class="flex-ac icon icon-next"></a>
  <a data-page-num="" href="javascript:;" class="flex-ac icon icon-last"></a>
</div>

2、js脚本部分

<script type="text/javascript">
//query转json
function buildJsonByQuery() {
    var json = {};
    var query = decodeURIComponent(location.search.substring(1));
    var args = query.split('&');
    var pair = [];
    for (var i = 0; i < args.length; i++) {
        pair = args[i].split('=');
        if (pair[0].length > 0) {
            json[pair[0]] = pair[1];
        }
    }
    return json;
}
//json转query
function buildQueryByJson(json) {
    var query = Object.keys(json).map(function(key) {
        return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
    }).join('&');
    return query;
}
//页面脚本
$(function() {
    //携带页码跳转方式
    $(document).on('click', '[data-page-num]', function(e) {
        e.stopPropagation();
        var url = location.pathname;
        var query = buildJsonByQuery();
        var page = $(this).attr('data-page-num');
        query.page = page;
        url += '?' + buildQueryByJson(query);
        location.href = url;
    });
    //ajax请求方式
    $(document).on('click', '[data-page-num]', function(e) {
        e.stopPropagation();
        var url = location.pathname;
        var query = buildJsonByQuery();
        var headers = {
            Accept: 'application/json;charset=utf-8'
        };
        var page = $(this).attr('data-page-num');
        query.page = page;
        $.ajax({
            async: true,
            type: 'POST',
            url: url,
            headers: headers,
            data: query,
            dataType: 'JSON',
            beforeSend: function() {
                console.log('beforeSend');
            },
            success: function(res) {
                console.log(res);
            },
            error: function(err) {
                console.log(err);
            }
        });
    });
});
</script>

3、css样式部分

:root {
    --primary-color: #1890ff;
    --primary-color-hover: #40a9ff;
    --primary-color-active: #096dd9;
}

html,
body {
    width: 100%;
    height: 100%;
    line-height: 1;
    font-family: -apple-system, BlinkMacSystemFont, segoe ui, Roboto, helvetica neue, Arial, noto sans, sans-serif, apple color emoji, segoe ui emoji, segoe ui symbol, noto color emoji;
    font-size: 14px;
    color: rgba(0, 0, 0, .85);
    -ms-text-size-adjust: 100%;
    -webkit-text-size-adjust: 100%;
}

a {
    text-decoration: none;
    color: #1890ff;
    color: var(--primary-color);
    outline: none;
    cursor: pointer;
}

a:hover {
    color: #40a9ff;
    color: var(--primary-color-hover);
}

a:active {
    color: #096dd9;
    color: var(--primary-color-active);
}

a:active,
a:hover,
a:focus {
    outline: 0;
}

.icon {
    /*省略*/
}

.icon:before {
    /*省略*/
}

.icon.icon-prev:before {
    /*省略*/
}

.icon.icon-next:before {
    /*省略*/
}

.icon.icon-first:before {
    /*省略*/
}

.icon.icon-last:before {
    /*省略*/
}

.flex-ac {
    display: -webkit-flex;
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-align-items: center;
    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;
    align-items: center;
}

.pages {
    width: 100%;
}

.pages>a {
    display: block;
    padding: 0 10px;
    height: 28px;
    border: 1px solid #d9d9d9;
    line-height: 26px;
    color: rgba(0, 0, 0, .85);
}

.pages>a:not(:last-child) {
    border-right: none;
}

.pages>a:hover {
    border-color: #40a9ff;
    border-color: var(--primary-color-hover);
    color: #40a9ff;
    color: var(--primary-color-hover);
}

.pages>a:hover+a {
    border-left-color: #40a9ff;
    border-left-color: var(--primary-color-hover);
}

.pages>a:active {
    border-color: #096dd9;
    border-color: var(--primary-color-active);
    color: #096dd9;
    color: var(--primary-color-active);
}

.pages>a.cur {
    border-color: #1890ff;
    border-color: var(--primary-color);
    color: #1890ff;
    color: var(--primary-color);
    cursor: not-allowed;
}

.pages>a.cur+a {
    border-left-color: #1890ff;
    border-left-color: var(--primary-color);
}

.pages>a.icon:before {
    font-size: 12px;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xmode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值