今天继续组件文章的分享,今天来讲讲分页组件。分页组件用在地方很多,特别是内容比较多,用分页能更好显示内容,下面讲下如何实现.
想要做一个组件,首先要想该组件时什么样子的,有什么样式,有什么功能,其结构是如何的.
这是我想实现的组件的样子,先分析一下如何实现
分析组件
功能分析
首先,先是上一页的按钮,后面紧跟着页数的按钮,而页数的按钮后跟下一页的按钮。有了按钮,也要有显示 当前页数总数有多少,那么就有显示现在总页数的部分。页面能显示的按钮有限,我们假设一行能显示10页左右吧, 那么超出10页之后的部分呢?那么在页数的部分就应该用省略号“...”适当的隐藏一些页数。并且在显示页数后面, 添加输入框和跳转确定按钮,来实现跳转到想跳转的页数的想法。
样式分析
对于页数的按钮,设置成容器盒子和文字大小一致,基本样式一致。对于当前页数则改变其背景的颜色和边框来与其他页数区分开来。 然后对于“上一页”和“下一页”的按钮,样式和页数差不多,但是长度要比页数长,并且在第一页和最后一页的时候对应上一页和下一页应该设置为禁止点击,所以也要是这部分样式。 页数总数显示样式也要适当控制,字体与页数差不多, 且盒子与前者保持相同类型。最后就是输入框和确定按钮与之前保持相类似风格。
结构分析
因为页数有时候要实现页面跳转,所以用button不太容易控制,因而这里直接用a标签即可,他们公属于一个类,把其命名为pageNum。 上一页和下一页也是a标签控制,不过对应应该用两个不同的类控制其行为,这里命名为preBtn和nextBtn。 到了显示总页数部分,直接用span标签控制即可。最后就是input输入框,确定按钮一样用a标签来做。 这就差不多完成了分析了,下面就开始来做。
样式和结构实现
我们先把分析时想到结构的东西先写,给定固定的数据,然后把样式也补上去。
代码清单:html代码
<div class="pages">
<a href="javascript:;" class="preBtn">上一页</a>
<a href="javascript:;" class="pageNum">1</a>
<a href="javascript:;" class="pageNum">2</a>
<a href="javascript:;" class="pageNum">3</a>
<a href="javascript:;" class="pageNum">4</a>
<a href="javascript:;" class="pageNum">5</a>
<a href="javascript:;" class="pageNum">6</a>
<a href="javascript:;" class="pageNum">7</a>
<a href="javascript:;" class="pageNum">8</a>
<a href="javascript:;" class="pageNum">9</a>
<a href="javascript:;" class="nextBtn">下一页</a>
<span>'共<b>9</b>页</span>
<span>到第<input type="number" class="pageInput" value="1"/>页</span>
<span class="changePage">确定</span>
</div>
有了最基础的样子
那么就把样式也加上去!!!
代码清单:css代码
/* 分页组件的共同样式 */
div.pages{
text-align: center;
color: #999999;
padding: 20px 20px 40px 0;
}
div.pages a{
text-decoration: none;
}
div.pages a,div.pages span{
display: inline-block;
box-sizing: border-box;
}
/* 当前页按钮 */
.current{
color: #ffffff;
background: #1ABC9C;
width: 40px;
height: 40px;
line-height: 40px;
border-radius: 3px;
}
/* 非当前页的按钮 */
.pageNum{
color: #666;
background: #fff;
width: 40px;
height: 40px;
line-height: 40px;
margin: 0 5px;
border-radius: 3px;
}
/* 当前页的下一页为当前页撑开空间 */
.nextpage{
margin: 0 5px;
}
/* 上一页按钮,下一页按钮,第一页和最后一页时禁止点击的上一页按钮和下一页按钮 */
.preBtn,.nextBtn,.disabled{
color: #666;
background: #fff;
width: 88px;
height: 42px;
line-height: 42px;
border-radius: 3px;
}
/* 翻页的输入框 */
.pageInput{
width: 50px;
height: 42px;
text-align: center;
box-sizing: border-box;
border: 1px solid #E6E6E6;
margin: 0 12px;
border-radius: 3px;
color: #666;
}
/* 确定翻页按钮 */
.changePage{
width: 48px;
height: 32px;
line-height: 32px;
border: 1px solid #E6E6E6;
margin-left: 10px;
cursor:pointer;
border-radius: 3px;
background: #fff;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type="number"]{
-moz-appearance: textfield;
}
上面就是最基本的样子啦!
功能实现
首先是分析一下,因为我们的页数都是用a标签做的,所以对于点击,应该要有事件发生,那么就得对每一个页数都要绑定点击事件。 最简单的想法就是获得页数的类pageNum,然后通过遍历,给每一个页数都绑定。那么对于上一页来说,每一次点击,我们需要 分析当前的页面是哪一页,然后只需要把当前页的类current-1即可,但是当页数在第一页时上一页不能用,所以此时设置一个类 current+1即可。
显示页面显示当前页面总数,那么总数也需要一个值来控制,并且其关乎之前pageNum遍历多少次。 然后到了输入框和确定按钮,输入框输入数字,确定按钮通过获得输入数值,先判断其是否大于页面总数,如果大于页面总数,那么就到达页面数最大的页数中去。 否则,设置当前页数为输入值。
新问题
那么新的问题来了,假设一行能显示9页,当下一页输入的值超过当前显示数9,那么下页怎么办?之前的页数又怎么办呢。 并且假如输入框中输入的值大于9,前面的数字怎么办。
那么我们就不能把数据写死,而是用js的方法,每一次点击都要重新清空节点然后重新添加回来。 页数总数,当前页数,还有每一页点击时实现的方法,这三个作为参数供用户输入然后重新把组件封装起来再调用。
对于封装那么我们就先有一个对象,封装要用到的方法和属性。那么把对象命名为pages吧。
首先这个对象要有点击事件的方法:
点击方法
上一页按钮:先获取当前页数current,然后把current-1替换掉current,然后重新加载结构,设置回调函数
下一页按钮:同理,先获取当前页数current,然后把current+1替换掉current,然后重新加载结构,设置回调函数
点击页数:先获取当前页数current,然后把点击页数的数字替换掉current,然后重新加载结构,设置回调函数
确定跳转页数按钮:先获取当前页数current,再获取输入框中的值,替换掉当前页数,然后重新加载结构,设置回调函数
对于重新加载结构,也把该方法放在对象中:
重新加载结构
每一次重新接在结构,就应该初始化节点。然后再对页面总数和当前页面作判断。
先判断总页面数是否大于1,加不同的上一页按钮
再判断不同情况下页面数什么时候选择用省略号代替,遍历加入数字按钮
再来加入下一页按钮和显示总页数
最后加入页面输入框和跳转
代码清单:js代码
addHtml:function(obj,page){
return (function(){
// 移除默认的节点
obj.empty();
//判断总页数是否大于1
if(page.pageNum>1){
obj.append('<a href="javascript:;" class="preBtn">上一页</a>')
}else{
obj.remove('.prevPage');
obj.append('<a href="javascript:;" class="disabled">上一页</a>')
}
// 中间页哪里用省略号...替代
if(page.current>4&&page.pageNum>4){ //页数和总页数都大于4
obj.append('<a href="javascript:;" class="pageNum">1</a>')
obj.append('<a href="javascript:;" class="pageNum">2</a>')
obj.append('<span>...</span>')
}
if(page.current>4&&page.current<=page.pageNum-5){
var start=page.current-2;
var end=page.current+2;
}else if(page.current>4&&page.current>page.pageNum-5){
var start=page.pageNum-4;
var end=page.pageNum;
}else{
var start=1;
var end=9;
}
// 遍历start到end为页数渲染结构
for (;start <= end;start++) {
if (start <= page.pageNum && start >=1) {
if (start == page.current) {
obj.append('<span class="current">'+ start +'</span>');
} else if(start == page.current+1){
obj.append('<a href="javascript:;" class="pageNum nextPage">'+ start +'</a>');
}else{
obj.append('<a href="javascript:;" class="pageNum">'+ start +'</a>');
}
}
}
//最后部分
if(end<page.pageNum){
obj.append('<span>...</span>');
}
/*下一页*/
if (page.current >= page.pageNum) {
obj.remove('.nextBtn');
obj.append('<span class="disabled">下一页</span>');
} else{
obj.append('<a href="javascript:;" class="nextBtn">下一页</a>');
}
//输入跳转部分
obj.append('<span>'+'共'+'<b>'+page.pageNum+'</b>'+'页,'+'</span>');
obj.append('<span>'+'到第'+'<input type="number" class="pageInput" value="1"/>'+'页'+'</span>');
obj.append('<span class="changePage">'+'确定'+'</span>');
}())
},
bindClick:function(obj,page){
return (function(){
//绑定上一页的点击事件
obj.on("click",".preBtn",function(){
var cur=parseInt(obj.children("span.current").text());
var current=$.extend(page,{"current":cur-1});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定数字按钮的点击事件
obj.on("click",".pageNum",function(){
var cur=parseInt($(this).text());
var current=$.extend(page,{"current":cur});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定下一页的点击事件
obj.on("click",".nextBtn",function(){
var cur=parseInt(obj.children("span.current").text());
var current=$.extend(page,{"current":cur+1});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定确定按钮的点击事件
obj.on("click",".changePage",function(){
var cur = parseInt($("input.pageInput").val());
var current=$.extend(page,{"current":cur});
if(cur<page.pageNum){
pages.addHtml(obj,{"current":cur,"pageNum":page.pageNum});
}else{
pages.addHtml(obj,{"current":page.pageNum,"pageNum":page.pageNum});
}
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
}())
}
有了基本的方法,我们也要有结构才能绑定方法和重新加载,那么再定义一个初始化的方法来调用对象的方法。
最后封装并创建一个方法作接口供外部使用,提供参数供改变。
代码清单:完整js代码
(function($){
var pages={
init:function(obj,page){
return (function(){
pages.addHtml(obj,page);
pages.bindClick(obj,page);
}());
},
addHtml:function(obj,page){
return (function(){
// 移除默认的节点
obj.empty();
//判断总页数是否大于1
if(page.pageNum>1){
obj.append('<a href="javascript:;" class="preBtn">上一页</a>')
}else{
obj.remove('.prevPage');
obj.append('<a href="javascript:;" class="disabled">上一页</a>')
}
// 中间页哪里用省略号...替代
if(page.current>4&&page.pageNum>4){ //页数和总页数都大于4
obj.append('<a href="javascript:;" class="pageNum">1</a>')
obj.append('<a href="javascript:;" class="pageNum">2</a>')
obj.append('<span>...</span>')
}
if(page.current>4&&page.current<=page.pageNum-5){
var start=page.current-2;
var end=page.current+2;
}else if(page.current>4&&page.current>page.pageNum-5){
var start=page.pageNum-4;
var end=page.pageNum;
}else{
var start=1;
var end=9;
}
// 遍历start到end为页数渲染结构
for (;start <= end;start++) {
if (start <= page.pageNum && start >=1) {
if (start == page.current) {
obj.append('<span class="current">'+ start +'</span>');
} else if(start == page.current+1){
obj.append('<a href="javascript:;" class="pageNum nextPage">'+ start +'</a>');
}else{
obj.append('<a href="javascript:;" class="pageNum">'+ start +'</a>');
}
}
}
//最后部分
if(end<page.pageNum){
obj.append('<span>...</span>');
}
/*下一页*/
if (page.current >= page.pageNum) {
obj.remove('.nextBtn');
obj.append('<span class="disabled">下一页</span>');
} else{
obj.append('<a href="javascript:;" class="nextBtn">下一页</a>');
}
//输入跳转部分
obj.append('<span>'+'共'+'<b>'+page.pageNum+'</b>'+'页,'+'</span>');
obj.append('<span>'+'到第'+'<input type="number" class="pageInput" value="1"/>'+'页'+'</span>');
obj.append('<span class="changePage">'+'确定'+'</span>');
}())
},
bindClick:function(obj,page){
return (function(){
//绑定上一页的点击事件
obj.on("click",".preBtn",function(){
var cur=parseInt(obj.children("span.current").text());
var current=$.extend(page,{"current":cur-1});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定数字按钮的点击事件
obj.on("click",".pageNum",function(){
var cur=parseInt($(this).text());
var current=$.extend(page,{"current":cur});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定下一页的点击事件
obj.on("click",".nextBtn",function(){
var cur=parseInt(obj.children("span.current").text());
var current=$.extend(page,{"current":cur+1});
pages.addHtml(obj,current);
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
//绑定确定按钮的点击事件
obj.on("click",".changePage",function(){
var cur = parseInt($("input.pageInput").val());
var current=$.extend(page,{"current":cur});
if(cur<page.pageNum){
pages.addHtml(obj,{"current":cur,"pageNum":page.pageNum});
}else{
pages.addHtml(obj,{"current":page.pageNum,"pageNum":page.pageNum});
}
if (typeof(page.backfun)=="function") {
page.backfun(current);
}
});
}())
}
}
$.fn.createPage = function(options){
var page = $.extend({
pageNum : 15,
current : 1,
backfun : function(){}
},options);
pages.init(this,page)
}
}(jQuery));
最后把html中调用封装的方法来创建出结构
组件实现!
最后附上html的完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>分页组件</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<script src="jquery-3.3.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="page.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="pages"></div>
<script type="text/javascript">
$(".pages").createPage({
pageNum: 100,
current: 1,
backfun: function(e) {
console.log(e);//回调
}
});
</script>
</body>
</html>
如果觉得本文不错的,希望评论或者点赞一下,给作者我一点鼓励,也希望自己能继续创作和努力下去!