上拉加载更多和下拉刷新通过better-scroll库实现,网络请求使用axios实现
样式
<style>
* {
margin: 0;
padding: 0;
}
ul,
ol {
list-style: none;
}
img {
display: block;
}
#sports-header {
width: 100%;
height: 50px;
background: #537bff;
display: flex;
justify-content: space-between;
align-items: center;
color: white;
font-size: 20px;
padding: 0 10px;
position: fixed;
top: 0;
z-index: 100;
}
#sports-main {
margin-top: 50px;
height: calc(100vh - 50px);
}
#sports-main ul {
background: white;
}
#sports-main ul li {
display: flex;
border-bottom: 1px #f7f7f7 solid;
margin: 0 18px;
padding: 20px 0;
}
#sports-main .sports-list-text {
flex: 1;
font-size: 18px;
line-height: 26px;
}
#sports-main .sports-list-text p:last-of-type {
font-size: 14px;
color: #828c9b;
display: flex;
margin-top: 10px;
}
#sports-main .sports-list-text p:last-of-type span {
margin-right: 10px;
}
#sports-main .sports-list-img {
width: 130px;
margin-left: 20px;
}
#sports-main .sports-list-img img {
width: 100%;
border-radius: 10px;
}
#loadingDown {
width: 100%;
position: absolute;
top: 60px;
z-index: -1;
text-align: center;
}
#loadingUp {
width: 100%;
text-align: center;
padding: 20px 0;
}
#loading {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 200px;
height: 30px;
line-height: 30px;
text-align: center;
z-index: 100;
}
</style>
页面结构
<header id="sports-header">
腾讯 | 体育
</header>
<div id="loadingDown"></div> -->
<main id="sports-main">
<div>
<ul class="sports-list">
</ul>
<div id="loadingUp"></div>
</div>
<div id="loading"></div>
</main>
template模板
<script id='tpl-sports' type='text/html'>
{
{
each list}}
<li>
<div class="sports-list-text">
<p>{
{
$value.title}}</p>
<p>
<span>{
{
$value.comment}}</span></span>
</p>
</div>
<div class="sports-list-img">
<img src="{
{$value.img}}" alt="">
</div>
</li>
{
{
/each}}
</script>
功能实现
<script>
const ul = document.querySelector('.sports-list');
const sportsList = document.querySelector('.sports-list');
const sportsMain = document.querySelector('#sports-main')
const loadingDown = document.querySelector('#loadingDown')
const loadingUp = document.querySelector('#loadingUp')
const loading = document.querySelector('#loading')
let now = 0;
initList();
initBetterScroll();
function initList() {
loading.innerHTML = 'loading...'
axios.post('/list', {
page: 0,
count: 10
}).then((res) => {
if (res.data.errcode == 0) {
setTimeout(() => {
loading.innerHTML = '';
ul.innerHTML = template('tpl-sports', res.data)
})
}
})
}
function initBetterScroll() {
let bs = BetterScroll.createBScroll(sportsMain, {
pullDownRefresh: {
threshold: 0
},
pullUpLoad: {
threshold: -10
}
})
bs.on('scrollStart', () => {
loadingDown.innerHTML = '下拉刷新'
loadingUp.innerHTML = '上拉加载更多'
})
bs.on('pullingDown', () => {
// console.log(111);
loadingDown.innerHTML = 'loading...'
axios.post('/list', {
page: 0,
count: 10
}).then((res) => {
setTimeout(function() {
if (res.data.errcode == 0) {
ul.innerHTML = template('tpl-sports', res.data)
}
loadingDown.innerHTML = '刷新成功'
bs.finishPullDown();
bs.refresh();
now = 0;
}, 1000)
})
})
bs.on('pullingUp', () => {
// console.log(222);
loadingUp.innerHTML = 'loading...';
axios.post('/list', {
page: ++now,
count: 10
}).then((res) => {
if (res.data.errcode == 0) {
setTimeout(function() {
ul.innerHTML += template('tpl-sports', res.data)
if (res.data.list.length) {
loadingUp.innerHTML = '加载成功'
} else {
loadingUp.innerHTML = '我也是有底线的'
}
bs.finishPullUp();
bs.refresh();
}, 1000)
}
})
})
}
</script>
后端路由实现
router.post('/list', async(ctx, next) => {
// console.log(cxt.request.body);
let args = [
{
field: 'page', type: 'number' },
{
field: 'count', type: 'number' }
]
let body = ctx.request.body;
for (let i = 0; i < args.length; i++) {
let item = args[i];
if (!Object.keys(body).includes(item.field)) {
ctx.body = {
errcode: -1,
errmsg: "参数个数错误"
};
return;
} else {
if (typeof body[item.field] != item.type) {
ctx.body = {
errcode: -2,
errmsg: "参数类型错误"
};
return;
}
}
}
let data = fs.readFileSync('./data/list.json');
data = JSON.parse(data);
let list = data.splice(body.page * body.count, body.count)
ctx.body = {
errcode: 0,
errmsg: 'ok',
list
}
})