前言
你在设计网站的时候是否有过这样的烦恼:“我设计的网站怎么就是从上到下一条线内容全部展开,一点都不好看!有没有什么好的办法呢?”,实现一个简单的分页功能就能帮你解决这样的烦恼,接下来我们就来看看如何实现一个简单的分页功能~
实现分页功能
需求分析
例如现在你有这样一个需求:对文章列表页面实现分页功能。
那么什么是分页功能呢?
简单来说就是实现以下四个按钮:
- 首页按钮:点击此按钮跳转到文章列表的首页。
- 上一页按钮:点击此按钮跳转到文章列表当前页的上一页。特殊处理:若当前文章列表在第一页,那么点击上一页则提醒用户“当前已在首页!”。
- 下一页按钮:点击此按钮跳转到文章列表当前页的下一页。特殊处理:若当前文章列表在最后一页,那么点击上一页则提醒用户“当前已在最后一页!”。
- 末页按钮:点击此按钮跳转到文章列表的最后一页。
最终实现效果如下:
接下来就来具体实现~
客户端开发
假设设计的文章版心如下
<!-- 版心 -->
<div class="container">
<!-- 右侧内容详情 -->
<div class="container-right" >
<!-- 每一篇博客包含标题, 摘要, 时间 (这里使用 ajax 请求到的文章数据进行填充)-->
<div id="artDiv">
</div>
<hr>
<div class="blog-pagnation-wrapper">
<button onclick="homePage()" class="blog-pagnation-item">首页</button>
<button onclick="prevPage()" class="blog-pagnation-item">上一页</button>
<span id="page"></span>
<button onclick="nextPage()" class="blog-pagnation-item">下一页</button>
<button onclick="lastPage()" class="blog-pagnation-item">末页</button>
</div>
</div>
</div>
编写 js 代码
创建三个全局变量,分别是 当前页数、每页显示最大文章数、文章总页数,通过这三个全局变量就可以实现4个按钮的分页功能。
- 首页按钮:将当前页数设置为1,再请求服务器获取当前博客列表,请求中的参数为当前页数。
- 上一页按钮:如果当前页数为1,则提示“当前已在首页”,若不在,则将请求服务器获取当前博客列表,请求中的参数为当前页数 + 1。
- 下一页按钮:和上一页按钮同理
- 末页按钮:将当前页设置为最后一页,并请求后端获取文章列表。
<script>
//当前页数
var curpage = 1;
//每页显示的最大文章数
var psize = 3;
//文章总页数
var pcount = 1;
// -----------------------这里以下“获取博客列表”可以部分忽略----------------------------------
//获取博客列表
function getArtList(pindex, psize) {
jQuery.ajax({
type: "GET",
url: "/art/listbypage",
data: {
"pindex": pindex,
"psize": psize
},
success: function (result) {
if (result != null && result.code == 200) {
//这里有两种情况,一种是有文章,一种是没有用户发表文章
if (result.data != null && result.data.list.length > 0) {
//有文章
var artListDiv = "";
for (var i = 0; i < result.data.list.length; i++) {
var artItem = result.data.list[i];
artListDiv += '<div class="blog">';
artListDiv += '<div class="title">' + artItem.title + '</div>';
artListDiv += '<div class="date">' + artItem.createtime + '</div>';
artListDiv += '<div class="desc">' + artItem.content + '</div>';
artListDiv += '<a href="blog_content.html?id=' + artItem.id + '" class="detail">查看全文 >></a>'
artListDiv += '</div>';
}
//将 html 填充进去
jQuery("#artDiv").html(artListDiv);
//显示当前页数
jQuery("#page").text(" 第 " + curpage + " 页 ");
//总页数
pcount = result.data.pcount;
} else {
//无文章
jQuery("#artDiv").html("<h2>暂无文章</h2>");
}
} else {
alert("博客列表获取失败!");
}
}
});
}
//初始化文章列表首页
getArtList(curpage, psize);
// -----------------------这里以上“获取博客列表”可以部分忽略----------------------------------
//分页功能处理
//首页按钮
function homePage() {
curpage = 1;
getArtList(curpage, psize);
}
//上一页按钮
function prevPage() {
if (curpage == 1) {
alert("当前已在首页!");
return;
} else {
getArtList(--curpage, psize);
}
}
//下一页按钮
function nextPage() {
if (curpage == pcount) {
alert("当前已在最后一页!");
return;
} else {
getArtList(++curpage, psize);
}
}
//末页按钮
function lastPage() {
curpage = pcount;
getArtList(curpage, psize);
}
</script>
服务器开发
服务器传入两个参数,反别是当前页码(pindex)、每页显示条数(psize),通过这两个参数如何实现分页查询呢(为什么要设计这两个参数)?
我们的服务器最后是要使用 MyBatis 对数据库进行修改的,那么分页的 sql 因该为 "select * from articleinfo limit #{psize} offset #{offset}",psize 我们以及约定好了(假设约定为3,也就是每页最多显示三条文章信息),那么 offset 的值怎么得来呢?
offset 是偏移量,也就是分页的起始下标(从0下标开始),就可以通过 当前页码(pindex)和 每页显示条数(psize) 计算得来!
这里需要一点数学推理,首先给出公式(方便后面理解): offset = (pindex - 1) * psize ,推理过程如下:
- 假设当前页码(pindex)为 1,每页显示(psize) 3 条,那么 offset 就是 0,因为从第 0 条开始显示。
- 假设当前页码(pindex)为 2,每页显示(psize) 3 条,那么 offset 就是 3,因为前三条数据(下标分别为:0、1、2)刚刚已经在第一页显示了,因此下一页就因该从下标为 3 的数据开始显示。
- 往后以此类推...
/**
* 博客列表分页功能
* @param pindex 当前页码
* @param psize 每页显示条数(约定每页显示 3 条)
* @return
*/
//limit 3 offset 0
//limit 3 offset 3
// offset 6
//offset = (pindex - 1) * psize
@RequestMapping("/listbypage")
public AjaxResult getlistByPage(Integer pindex, Integer psize) {
//非空校验
if(pindex == null || pindex < 1) {
pindex = 1;
}
if(psize == null || psize < 3) {
psize = 3;
}
//公式计算得到 offset
int offset = (pindex - 1) * psize;
List<ArticleInfo> list = articleService.getListByPage(psize, offset);
//当前列表有多少也
//a.总共有多少条数据
int totalCount = articleService.getArtAllCount();
//b.总条数 / psize
double pcountdb = totalCount / (psize * 1.0);
//c.使用进1法得到总页数
int pcount = (int) Math.ceil(pcountdb);
HashMap<String, Object> result = new HashMap<>();
result.put("list", list);
result.put("pcount", pcount);
return AjaxResult.success(result);
}
前后端交互——两种前端得到 文章总页数 的方法,那种更合适?
两种方法分别如下
- 后端使用哈希表带上 文章总数和文章列表 传送给前端,前端进行一次 HTTP 请求完成分页功能的实现”。(刚刚所讲的分页功能就是这样实现的)
- 前后端使用两次 HTTP 请求完成分页功能,也就是前端发送两次 ajax 请求后端,一次是请求文章列表,一次是请求总页数。
第二种方法前端代码如下:
<script>
//当前页数
var curpage = 1;
//每页显示的最大文章数
var psize = 3;
//文章总页数
var pcount = 1;
//文章总数
var allCount = 1;
function getAllCount() {
jQuery.ajax({
url: "/art/allcount" ,
type: "GET",
async: false, //async 是设置状态的(同步执行和异步执行),默认为 true 异步执行,有可能会出现"抢占执行"
success: function (result) {
if (result != null && result.code == 200) {
allCount = result.data;
}
}
});
}
getAllCount();
//获取博客列表
function getArtList(pindex, psize) {
jQuery.ajax({
type: "GET",
url: "/art/listbypage",
data: {
"pindex": pindex,
"psize": psize
},
success: function (result) {
if (result != null && result.code == 200) {
//这里有两种情况,一种是有文章,一种是没有用户发表文章
if (result.data != null && result.data.length > 0) {
//有文章
var artListDiv = "";
for (var i = 0; i < result.data.length; i++) {
var artItem = result.data[i];
artListDiv += '<div class="blog">';
artListDiv += '<div class="title">' + artItem.title + '</div>';
artListDiv += '<div class="date">' + artItem.createtime + '</div>';
artListDiv += '<div class="desc">' + artItem.content + '</div>';
artListDiv += '<a href="blog_content.html?id=' + artItem.id + '" class="detail">查看全文 >></a>'
artListDiv += '</div>';
}
//将 html 填充进去
jQuery("#artDiv").html(artListDiv);
//显示当前页数
jQuery("#page").text(" 第 " + curpage + " 页 ");
} else {
//无文章
jQuery("#artDiv").html("<h2>暂无文章</h2>");
}
} else {
alert("博客列表获取失败!");
}
}
});
}
//初始化首页
getArtList(curpage, psize);
//分页功能处理
//首页按钮
function homePage() {
curpage = 1;
getArtList(curpage, psize);
}
//上一页按钮
function prevPage() {
if (curpage == 1) {
alert("当前已在首页!");
return;
} else {
getArtList(--curpage, psize);
}
}
//下一页按钮
function nextPage() {
if (curpage == pcount) {
alert("当前已在最后一页!");
return;
} else {
getArtList(++curpage, psize);
}
}
//末页按钮
function lastPage() {
curpage = pcount;
getArtList(curpage, psize);
}
</script>
那种方法更好呢?
两种方法都可以,没有明确的好坏之分,要说有的话,方法二需要进行两次 HTTP 请求,而 HTTP 建立连接时需要时间的,因此在效率上,第一种方式更优,并且企业中最常用的也是第一种方式。