エフェクト画像
序文
はは、ブログを書くたびに一言書くのが好きです。これはもともとフロントエンドのものでしたが、最終的な作業が必要なため、バックエンドの学生は開業を余儀なくされました。
事前にフルスタックを学ぶ
ページングロジックの説明
1.数字ボタン
常に7つの数字ボタンがあります。現在のページの左側と右側のボタンで十分な場合は、左側と右側に3つのボタンがあります。現在のページのボタンの左側にあるボタンが3つ未満の場合、番号ボタングループの範囲は[1、6]です。現在のページのボタンの右側にあるボタンが3つ未満の場合、番号ボタングループの範囲は[5、11]です。
3.最初のページと最後のページ
7つの数字ボタンに最初のページ(最初のページ)が表示されている場合は、「最初の」ボタンを表示する必要はありません。同様に、7つの数字ボタンに11ページ(最後のページ)が表示されている場合は、必要ありません。 「最後」ボタンを表示します。
4.前のページ、次のページ
前のページがない場合(現在は1ページ)、[前へ]ボタンは表示されません。次のページがない場合(現在のページが最後のページにある場合)、[次へ]ボタンを表示する必要はありません。 。
コード
ロジックは少し複雑に見えます。コーディングのアイデアは明確でなければなりません。そうでないと、詳細が多く、時間がかかり、多少の小さなバグがあるため、書くのが不快になる可能性があります。
次のコードには、詳細なコメントとコーディングのアイデアの概要が含まれています。コメントを削除してください。キーコードは10行または20行以内です。
ブートストラップの導入、わずかに...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- 不设置的话,手机端不会进行响应式布局 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>商品列表页</title>
<!-- 引入Bootstrap核心样式文件 -->
<link rel="stylesheet" href="lib/bootstrap4/css/bootstrap.css">
<style>
/* 分页按钮样式复写 */
/*.page-link {*/
/* color: #8c8c8c;*/
/*}*/
/*.page-link:hover {*/
/* color: #007bff;*/
/*}*/
</style>
<!--站点图标-->
<!-- ... -->
</head>
<body>
<div class="page-helper mt-5 d-flex justify-content-center">
</div>
<!-- js的顺序不能乱 -->
<script src="lib/jquery/jquery.min.js"></script>
<!-- bootstrap.min.js依赖jquery -->
<script src="lib/bootstrap4/js/bootstrap.min.js"></script>
<script>
// 11页
$(function () {
let API_URL = 'test_pagehelper.html';
let curPage = getUrlParam('page');
if (curPage === undefined) {
curPage = 2;
}
console.log(curPage);
let btnHtml = pageHelper(API_URL, parseInt(curPage), 108, 10, 3, '')
$('div.page-helper').append(btnHtml);
});
/**
* 生成分页按钮的html代码
* @param curPage 当前页。理应由前端传给后端,但是前端的传参有可能超出实际范围,这就必须交由
* 后端来纠正之后,再查询对应页码的数据。然后后端将纠正后的当前页返回给前端,
* 以便前端来渲染页码按钮组。如果不传,由后端返回默认值1
* @param total 总记录数。实际上,后端可以直接返回总页数就可以了,只不过有一定局限性:假如
* 前端还需要显示总记录数,凭借总页数和每页记录数,是无法计算出总记录数的。而返
* 回总记录数,前端可以自行计算总页数,同时还可以额外显示总记录数
* @param count 每页显示的记录数,由前端传给后端。如果不传,使用后端定义的默认值
* @param sideBtnCount 当前页按钮的左边有多少个按钮,不需要传给后端
* @param urlParamsStr 点击页码切换页面时,携带的条件参数的字符串,拼接在url后面。由后端定义并传给
* 前端。后端接口并负责接收,按照自己定义的规则进行解析,拆解参数。
* 例子:&name=ysq&age=21。前面的&不能少
*/
function pageHelper(API_URL, curPage, total, count, sideBtnCount, urlParamsStr) {
// 计算总页数
let pageCount = Math.ceil(total / count);
let leftPage, rightPage;
if (pageCount <= 2 * sideBtnCount + 1) {
leftPage = 1;
rightPage = pageCount;
} else {
// 计算按钮组最左端和最右端的页码
// 将[1, pageCount]分为3个区间:
// [1, sideBtnCount],[sideBtnCount+1, pageCount-sideBtnCount],[pageCount-sideBtnCount+1, pageCount]
if (curPage > sideBtnCount && curPage <= pageCount - sideBtnCount) {
// [sideBtnCount+1, pageCount-sideBtnCount]
leftPage = curPage - sideBtnCount;
rightPage = curPage + sideBtnCount;
} else if (curPage <= sideBtnCount) {
// [1, sideBtnCount]
leftPage = 1;
rightPage = 2 * sideBtnCount + 1;
// 越界时,修正当前页
if (curPage < 1) {
curPage = 1;
}
} else if (curPage > pageCount - sideBtnCount) {
// [pageCount-sideBtnCount+1, pageCount]
leftPage = pageCount - 2 * sideBtnCount;
rightPage = pageCount;
// 越界时,修正当前页
if (curPage > pageCount) {
curPage = pageCount;
}
}
}
return "<div class='pagination'>" +
firstBtn('First') +
preBtn('Pre') +
numBtn(leftPage, rightPage) +
nextBtn('Next') +
lastBtn('Last') +
"</div>";
/**
* 返回一个可点击的按钮的html代码
* @param contentHtml 按钮中的内容
*/
function clickableBtn(contentHtml, num) {
return `<li class='page-item'><a class='page-link' href='${API_URL}?page=${num}${urlParamsStr}'>${contentHtml}</a></li>`;
}
/**
* 返回一个当前页按钮的html代码
* @param contentHtml
*/
function currentBtn(contentHtml) {
return `<li class='page-item active'><span class='page-link'>${contentHtml}</span></li>`;
}
/**
* 返回上一页按钮的html代码
* @param contentHtml
*/
function preBtn(contentHtml) {
if (curPage <= 1) {
return ''; // 我这里直接返回空,你也可以根据你的喜好,返回禁用点击的按钮
}
return clickableBtn(contentHtml, curPage - 1);
}
/**
* 返回下一页按钮的html代码
* @param contentHtml
*/
function nextBtn(contentHtml) {
if (curPage >= pageCount) {
return '';
}
return clickableBtn(contentHtml, curPage + 1);
}
/**
* 返回首页按钮的html代码
* @param contentHtml
*/
function firstBtn(contentHtml) {
if (leftPage <= 1) {
// 如果首页(1)已经显示在了按钮组(>=leftPage)当中,则不需要首页按钮,这里我直接返回空
return '';
}
return clickableBtn(contentHtml, 1);
}
/**
* 返回末页按钮的html代码
* @param contentHtml
*/
function lastBtn(contentHtml) {
if (pageCount <= rightPage) {
// 如果末页(pageCount)已经显示在了按钮组(<=rightPage)当中,则不需要首页按钮,这里我直接返回空
return '';
}
return clickableBtn(contentHtml, pageCount);
}
/**
* 生成[left, right]区间的按钮的html代码
* @param left
* @param right
*/
function numBtn(left, right) {
let btnHtml = '';
for (let i = left; i <= right; i++) {
if (i === curPage) { // 当前页
btnHtml += currentBtn(i);
} else {
btnHtml += clickableBtn(i, i);
}
}
return btnHtml;
}
}
// 获取指定的路径参数,获取不到返回空串
function getUrlParam(key) {
// ? 后面的
let searchStr = window.location.search.substring(1);
console.log(searchStr);
let paramMap = new Array();
let paramEntrys = searchStr.split('&');
for(let i=0; i<paramEntrys.length; i++) {
let entry = paramEntrys[i].split('=');
paramMap[ entry[0] ] = entry[1];
}
console.log(paramMap);
return paramMap[key];
}
</script>
</body>
</html>