无限分页设计与实现

最近接手一个微信端的的项目,客户要求在文章列表页面不要用分页。然后项目经理就交代下来,用瀑布流吧(他对前端并不了解),开发组的顿姐姐就说是不是无限分页呀… 然后我就开始自行脑补瀑布流,无限分页,原理不还是一样嘛。自行研究了一下,就开始了造轮子之路…
当然,欢迎来原文看看,原文

1.基本思路

1.1 概述

无限分页,就是说页面在不显示页码,不需要用户去点击页码,使用技术手段实现页面滚动到某一时刻进行加载下一页内容,并且陈列到页面上。这不就是赤裸裸的瀑布流一样的原理么。

1.2 脑补一下

先来补充一个sql语句知识,当然这里只做MySQL的实例

1
select * from imgs limit 0,8;

查询语句的意思:查询imgs表的所有内容,显示第一页的8条内容从第一条数据开始算起
那么第二页怎么写呢:(直接写出前四页的sql语句,一起来找规律)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
第一页     select * from imgs limit 0,8;
结果:
+----+------------+
| id | src |
+----+------------+
| 1 | img/01.jpg |
| 2 | img/02.jpg |
| 3 | img/03.jpg |
| 4 | img/01.jpg |
| 5 | img/01.jpg |
| 6 | img/01.jpg |
| 7 | img/01.jpg |
| 8 | img/01.jpg |
+----+------------+
第二页 select * from imgs limit 8,8;
结果:
+----+------------+
| id | src |
+----+------------+
| 9 | img/01.jpg |
| 10 | img/01.jpg |
| 11 | img/01.jpg |
| 12 | img/01.jpg |
| 13 | img/01.jpg |
| 14 | img/02.jpg |
| 15 | img/02.jpg |
| 16 | img/02.jpg |
+----+------------+
第三页 select * from imgs limit 16,8;
结果:
+----+------------+
| id | src |
+----+------------+
| 17 | img/02.jpg |
| 18 | img/02.jpg |
| 19 | img/02.jpg |
| 20 | img/02.jpg |
| 21 | img/02.jpg |
| 22 | img/02.jpg |
| 23 | img/02.jpg |
| 24 | img/03.jpg |
+----+------------+
第四页 select * from imgs limit 24,8;
结果:
+----+------------+
| id | src |
+----+------------+
| 25 | img/03.jpg |
| 26 | img/03.jpg |
| 27 | img/03.jpg |
| 28 | img/03.jpg |
| 29 | img/03.jpg |
| 30 | img/03.jpg |
| 31 | img/02.jpg |
| 32 | img/02.jpg |
+----+------------+

好了,规律想必已经找到了。不过还是要大致说一下这个sql语句意思。
‘limit’后面有两个数字,这就输关键所在,第一个数字是开始的索引值,0代表第一个开始,8代表显示条数,根据第二个数字有规律的改变第一个数字,分页效果就出来了。

1.3 js设计原理

页面总是有个宽度高度的,页面加载完毕,上下滚动页面,有个触发事件,每次到一个合适的条件,就触发事件进行ajax的请求,并将返回的数据加进页面内,就完成一次加载(或者说完成一次加载下一页数据的请求),在代码行内的注释进行更详细的说明

2.代码

2.1 html代码

1
2
3
4
5
6
7
8
<div class="container">
<div class="wrap">
<!-- 这里放加载的数据-->
</div>
<div class="loader">
<!-- 这里放加载时候的加载动画,还有加载完毕后提示信息 -->
</div>
</div>

2.2 css代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
	 * {
margin: 0;
padding: 0;
}

.container {
width: 640px;
margin: 0 auto;
background: #FFF;
}

.container a {
display: inline-block;
margin: 10px;
}

.container a img {
width: 100%;
}

.loader {
width: 100%;
text-align: center;
height: 50px;
line-height: 50px;
}
/* 预设加载动画,css3做的动画效果 */
.dot {
width: 18px;
height: 18px;
background: #3ac;
border-radius: 100%;
display: inline-block;
animation: slide 1s infinite;
-webkit-animation: slide 1s infinite;
margin-left:5px;
margin-right:5px;
}
.dot:nth-child(1) {
animation-delay: 0.1s;
-webkit-animation-delay: 0.1s;
background: #ccc;
}

.dot:nth-child(2) {
animation-delay: 0.2s;
-webkit-animation-delay: 0.2s;
background: #ccc;
}

.dot:nth-child(3) {
animation-delay: 0.3s;
-webkit-animation-delay: 0.3s;
background: #ccc;
}
.dot:nth-child(4) {
animation-delay: 0.4s;
-webkit-animation-delay: 0.4s;
background: #ccc;
}

.dot:nth-child(5) {
animation-delay: 0.5s;
-webkit-animation-delay: 0.5s;
background: #ccc;
}

@-webkit-keyframes slide {
0% {
transform: scale(1);
-webkit-transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(1.2);
-webkit-transform: scale(1.2);
}
100% {
transform: scale(1);
-webkit-transform: scale(1);
}
}

@keyframes slide {
0% {
transform: scale(1);
-webkit-transform: scale(1);
}
50% {
opacity: 0.3;
transform: scale(1.2);
-webkit-transform: scale(1.2);
}
100% {
transform: scale(1);
-webkit-transform: scale(1);
}
}

这里放了一个css3做的加载动画,也是在其他博客上看到的,挺好玩,拿来用用

2.3 js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
$(function () {
//预设全局变量page,就是用来当做'limit'后面的第一个数字
var page = 0;
//给预设一个全局变量,判断一次请求是否完毕,完毕后才能进行下一次请求,防止多次重复进行请求
var status = true;
//给预设一个全局变量,判断数据是否已经完全加载完毕,并且已经没有可以再次加载的数据,防止已经没有可加载后还会进行请求,
var dataStatu = true;
$(window).scroll(function () {
//滚动的高度
var scrollTop = $(window).scrollTop();
//浏览器可视区域的高度
var screenHei = $(window).height();
//文档的总高度
var bodyHei = $(document).height();
//计算一个差值,通过这个差值,判断是否进行ajax请求
var c = bodyHei - screenHei - scrollTop;
if (c < 100) {
//判断是否可以加载数据
if (dataStatu == true && status == true) {
//可以加载数据,把status状态修改为false
status = false;
//重置容器‘.loader’为空白
$('.loader').html('');
//往容器‘.loader’加进加载动画
var str = '<div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div><div class="dot"></div>';
$('.loader').html(str);
//调用加载数据的函数
getData();
}

}

});
//页面加载时先进行一次数据请求
getData();

function getData() {
//引用jq的ajax方法,不解释,好用就行
$.ajax({
//看清楚url带的get参数
url: './control/getData.php?page=' + page + '&pageNum=8',
type: 'get',
dataType: 'text',
success: function (data) {
//处理返回的json数据
var data = JSON.parse(data);
//请求已经发送,并且请求的数据已经返回,重置状态码status为false,准备下一次的请求
status = true;
//sql语句原理说过‘limit’后第一个数字有规律变化,就在这里
page += 8;
//让数据有个缓冲的过程去过渡一下,给两秒时间,两秒后把请求的数据放进网页里
setTimeout(function(){
//重置容器‘.loader’为空白
$('.loader').html(' ');
//判断返回的数据是否为空,由于是处理json后的数据,当然是数组,判断 数组长度是否为0即可
if (data.length == 0) {
//当所有数据已经加载完毕,没有可以在加载的数据,将状态码dataStatu设置为false,不再进行数据请求
dataStatu = false;
console.log('没有数据加载了');
//容器‘.loader’填写数据已经加载完毕的提示
var str = '没有可加载数据了';
$('.loader').html(str);
} else {
console.log('还有数据加载呢.......');
}
//将请求的数据遍历出来,拼接进字符串
var str = '';
for (var i = 0; i < data.length; i++) {
str += '<a href="">';
str += '<img src="' + data[i].src + '" alt="">';
str += '</a>';
}
//将凭借出来的字符串追加进容器内
$('.wrap').append(str);
},2000)


},
error: function (statuCode) {
console.log(statuCode);
}
});
}



})

3、补充说明

对于page,我这里是get传递0,8,16,24…实际环境下,需要问一下后台人员有木有对page在后台处理,他们可能需要1,2,3,4,5…..就好了;
还有ajax的url参数‘pageNum=8’,后台直接设置的话,前端就不需要传送;
总而言之,实际操作时,还得和后台人员沟通,原理就是这么个原理,有不恰当的地方,希望过路的大神们不吝赐教

4、在线演示

在线演示