随着网站的数据越来越多,以及用户访问量的增加。网页数据从最初的一次性加载全部数据到后来的每次点击按一定数量的查询结果返回数据,于是有了分页功能。
随着网络的发展,人们更注重于网站的体验效果,传统网站实现了基本的分页功能,但用户每次都需要手动去点击某一页来实现翻页,这大大影响了网站的体验效果,于是有人提出了自动分页,看到那就加载到哪,既减少了手动操作,又大大提升了网站加载速度,减少了往回翻页的网络延迟以及卡顿。现在很多的网站使用了自动填充分页功能,其中就有当年比较火的QQ空间。
本文就循环渐进地一步步分析讲述一下其中的原理。
条件:
- 当初始化页面数据较少时
- 当数据较多,出现滚动条,并且滚动到底部时
需要了解的基本点:
- 内容真实高度(scrollHeight 或 offsetHeight)
- 可视高度 即浏览器视窗高度(innerHeight 或 clientHeight )
- 向上滚动的高度(scrollTop)
- 隐藏的高度(通过计算得出用于判断是否达到触发分页条件)
图片时临时画的,可能比较丑,大概就是这样的
实现思路:
- 由于每个人的显示屏高度不一,加载数据也就不在局限于传统的固定加载多少条数据,采取的做法是内容过少时则不断加载数据,直到数据超过视窗
- 如果数据超过视窗,则判断隐藏的部分是否小于一定的值(即滚动到底部时),如果小于则触发加载数据
注:每次应该判断返回的数据是否等于每页的加载数,如果小于则应该停止加载数据
接下来我们就按照思路来开始实现一下:
<!DOCTYPE html>
<html>
<head>
<title>自动分页预加载测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
.tips-box{
position: fixed;
display: block;
opacity: 1;
left: calc(50% - 50px);
width: 100px;
bottom: 20px;
color: red;
height: 40px;
line-height: 40px;
text-align: center;
background: #f5f5f5;
border-radius:5px;
transition: all 1s;
-webkit-transition: all 1s;
}
.hidden{
opacity: 0;
background: #fff;
}
.show{
opacity: 1;
background: #f5f5f5;
}
</style>
</head>
<body>
<div id="dataList"></div>
<div id="tips" class="tips-box">loading……</div>
<script>
// 定义当前属于第几页
let pageIndex = 0;
// 获取提示语对象
let tips = document.getElementById('tips')
// 定义 条件判断 函数
let _calcFuc = () => {
// 获取内容真实高度
let cententHeight = Math.max(document.body.offsetHeight, document.body.scrollHeight)
// 获取浏览器可视高度
let viewHeight = window.innerHeight ||
document.body.clientHeight ||
document.documentElement.clientHeight || 0
// 获取滚动的高度
let scrollHeight = document.body.scrollTop ||
document.documentElement.scrollTop ||
window.pageYOffset || 0
// 获取底部隐藏的高度
let bottomHiddenHeight = cententHeight - viewHeight - scrollHeight
//判断底部隐藏的高度是否小于某个值(这里设置为 10)
return bottomHiddenHeight < 10
}
// 定义 查询数据 函数
let _queryData = () => {
// TODO 假数据
let html = ''
for (let i = 0; i < 10; i ++) {
html += '这是第 ' + pageIndex + ' 页的数据'
}
let para = document.createElement('p')
let node = document.createTextNode(html)
para.appendChild(node)
let element = document.getElementById('dataList')
element.appendChild(para)
pageIndex ++
// 定时加载
_setTimeLoading ()
//调整样式
tips.classList.remove('show')
tips.classList.add('hidden')
}
// 定义 加载过程 函数
let _Loading = () => {
if (!_calcFuc()) return _setTimeLoading()
//调整样式
tips.classList.remove('hidden')
tips.classList.add('show')
setTimeout(_queryData, 500)
}
// 定义 定时监控 函数
let _setTimeLoading = () => setTimeout(_Loading, 700) // 时间自定义
//初始化
_Loading()
</script>
</body>
</html>
只要思路清晰,我们很容易就编写出来了,代码量精简,这种纯js的方式,避免了加载第三方插件使页面不再冗余,不用考虑是否是移动端
当然啦,这个做成组件效果更好,可以复用
如果你有更好的方案,大家可以交流交流……