最近在做移动端开发,移动端的性能不如 PC
端,屏幕页没有 PC
大,需要我们优化的东西很多;在工作中我所做的移动端小页面,无一例外的都是将网页嵌入到安卓或者 IOS
里面去。
问题:如果数据太多前端一次性渲染或者请求所有数据,就不能做到用户体验和用户效果最佳 解决方案: 移动端分页,滚动到页面底部重新请求接口,然后把上次请求的数据和这一次请求的数据拼接到一个数组里面
关于原生的滚动 scroll
事件会失效这个问题坑大了,有兴趣可以看看 解决工作bug或者需求系列文章
因为用的是 vue
所以会好一点,没有那么坑,但是很多 css
样式都是缺一不可的 实现代码:
<template>
<div class='wrapper'>
<p class="refreshText">{{text}}</p>
<ul class='refreshContainer' @touchstart='getStart' @touchmove='getMove' @touchend='getEnd' @scroll="onScroll($event)">
<li class='freshContainer' v-for='item in listData' :key='item.value'>{{item.label}}</li>
</ul>
</div>
</template>
<script>
export default {
// 当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作;
// 下拉到一定值时,显示松手释放后的操作提示;
// 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作。
data(){
return {
text:"",
listData:[{
label:'测试数据001',
value:'hjh'
},{
label:'测试数据002',
value:2
},{
label:'测试数据003',
value:3
},{
label:'测试数据004',
value:4
},{
label:'测试数据005',
value:5
},{
label:'测试数据006',
value:6
},{
label:'测试数据007',
value:7
},{
label:'测试数据008',
value:8
},{
label:'测试数据009',
value:9
},{
label:'测试数据010',
value:10
},{
label:'测试数据0011',
value:11
}]
}
},
methods:{
onScroll (event) {
const target = event.target
// 滚动条的总高度
const scrollHeight = target.scrollHeight
// 可视区的高度
const clientHeight = target.clientHeight
// 距离顶部的距离
const scrollTop = target.scrollTop
console.log('滚动条的总高度',scrollHeight);
console.log('可视区的高度',clientHeight);
console.log('距离顶部的距离',scrollTop);
// 滚动到底部
if (scrollTop + clientHeight >= scrollHeight - 80) {
// 这里可以进行数据分页请求了this.getListMore
this.listData.push({
label:'测试数据0012',
value:12
},{
label:'测试数据0013',
value:13
},{
label:'测试数据004',
value:14
},{
label:'测试数据0015',
value:15
},{
label:'测试数据0016',
value:1
},{
label:'测试数据0016',
value:16
},{
label:'测试数据0017',
value:17
},{
label:'测试数据0018',
value:18
},{
label:'测试数据0019',
value:19
},{
label:'测试数据00100',
value:100
},{
label:'测试数据00101',
value:101
},{
label:'测试数据00102',
value:102
},{
label:'测试数据00103',
value:103
})
console.log('滚动事件',event);
}
}
}
}
</script>
<style>
html,
body,
.body-container {
height: 100%;//必须有
}
.wrapper {
width: 100%;
height: 100%;//必须有
}
ul {
height: 100%;//必须有
border: 1px red solid;
overflow: auto;//必须有
}
ul li {
width: 100%;
line-height: 100px;
/* border: 1px red solid; */
text-align: center;
}
.refreshText {
display: flex;
justify-content: center;
align-items: center;
/* height: 50px; */
border: 1px red solid;
}
</style>
复制代码
解决方案: 监听原生的 touchstart
,touchmove
,touchend
事件,这个还好,没啥问题
实现代码:
<p class="refreshText">{{text}}</p>
<ul class='refreshContainer' @touchstart='getStart' @touchmove='getMove' @touchend='getEnd'>
<li v-for='item in listData' :key='item.value'>{{item.label}}</li>
</ul>
<script>
export default {
// 当前手势滑动位置与初始位置差值大于零时,提示正在进行下拉刷新操作;
// 下拉到一定值时,显示松手释放后的操作提示;
// 下拉到达设定最大值松手时,执行回调,提示正在进行更新操作。
data(){
return {
text:"",
listData:[{
label:'测试数据001',
value:'hjh'
},{
label:'测试数据002',
value:2
},{
label:'测试数据003',
value:3
},{
label:'测试数据004',
value:4
},{
label:'测试数据005',
value:5
},{
label:'测试数据006',
value:6
},{
label:'测试数据007',
value:7
},{
label:'测试数据008',
value:8
},{
label:'测试数据009',
value:9
},{
label:'测试数据010',
value:10
},{
label:'测试数据0011',
value:11
},{
label:'测试数据0012',
value:12
},{
label:'测试数据0013',
value:13
},{
label:'测试数据004',
value:14
},{
label:'测试数据0015',
value:15
},{
label:'测试数据0016',
value:1
},{
label:'测试数据0016',
value:16
},{
label:'测试数据0017',
value:17
},{
label:'测试数据0018',
value:18
},{
label:'测试数据0019',
value:19
},{
label:'测试数据00100',
value:100
},{
label:'测试数据00101',
value:101
},{
label:'测试数据00102',
value:102
},{
label:'测试数据00103',
value:103
}],
startPosition:0,
movePostion:0,
refreshContainer:"",
refreshText:""
}
},
methods:{
getStart(e){
this.refreshContainer = document.querySelector('.refreshContainer')
this.startPosition = e.touches[0].pageY
this.refreshContainer.style.position = 'relative';
this.refreshContainer.style.transition = 'transform 0s';
},
getMove(e){
this.movePostion = e.touches[0].pageY
let transitionHeight = this.movePostion - this.startPosition
this.refreshText = document.querySelector('.refreshText')
if(transitionHeight > 0 &&transitionHeight < 50){
this.refreshText.style.height = transitionHeight+'px';
}else{
this.refreshText .style.height = '50px';
}
if (transitionHeight > 0 && transitionHeight < 100) {
this.text = '下拉刷新';
this.refreshContainer.style.transform = 'translateY('+transitionHeight+'px)';
if (transitionHeight > 50) {
this.text = '释放更新';
}
}
},
getEnd(){
this.refreshContainer.style.transition = 'transform 0.5s ease 1s';
this.refreshContainer.style.transform = 'translateY(0px)';
this.text = '更新中...';
this.refreshText.style.height = '0px';
this.text = '';
// 接口请求什么的事情
},
}
}
</script>
复制代码
详细介绍请参考H5下拉刷新和上拉加载实现原理浅析
大概原理是这样的,样式什么的瞎写的,有兴趣可以自己好好写一下样式。
博客会保持随时更新 sunseekers.cn/