最终达到的目标效果
将要用到
监听页面滚动事件:onPageScrollhtml
获取节点信息uni.createSelectorQuery()node
标签布局
<template> <view class="content"> <!--目标节点--> <view class="text-area" id="listArea"> <view class="square" v-for="(v,i) in info" :key='i'>{{v}}</view> </view> </view> </template>
js部分
export default { data() { return { screenHeight: 0, //屏幕高度 info: [],//展现的列表数据 isLoading: false, //防止频繁触发 bottomDistinct:200//距离底部多少像素时触发 } }, onLoad() { //页面加载时取得屏幕高度 this.screenHeight = uni.getSystemInfoSync().screenHeight; //测试数据(初始化) this.info=new Array(5).fill(0).map((v,i)=>i+1); }, methods: { /** * 页面滑动事件 */ onPageScroll: function(e) { const { scrollTop//滚动条距离页面顶部的像素 } = e; //防止重复触发 if(this.isLoading){ return; } //获取SelectorQuery 对象实例 const query = uni.createSelectorQuery().in(this); //为listArea节点绑定查询请求 query.select('#listArea').boundingClientRect(data => { let { height//listArea节点的高度 } = data; //若是设置的事件触发距离 大于等于 (节点的高度-屏幕高度-滚动条到顶部的距离) if(this.bottomDistinct>=height-this.screenHeight-scrollTop){ //阻止事件重复触发 this.isLoading=true; //模拟异步加载数据 uni.showToast({ title:"获取新数据" }) setTimeout(()=>{ //测试数据 let arr=new Array(5).fill(0); arr=arr.map((v,i)=>this.info.length+i+1); //数据填充 this.info=this.info.concat(arr); this.isLoading=false; }, 1500); } }).exec(); } } }
完整demo代码
<template> <view class="content"> <view class="text-area" id="listArea"> <view class="square" v-for="(v,i) in info" :key='i'>{{v}}</view> </view> </view> </template> <script> export default { data() { return { screenHeight: 0, //屏幕高度 info: [],//展现的列表数据 isLoading: false, //防止频繁触发 bottomDistinct:200//距离底部多少像素时触发 } }, onLoad() { //页面加载时取得屏幕高度 this.screenHeight = uni.getSystemInfoSync().screenHeight; //数据初始化 this.info=new Array(5).fill(0).map((v,i)=>i+1); }, methods: { /** * 页面滑动事件 */ onPageScroll: function(e) { const { scrollTop//滚动条距离页面顶部的像素 } = e; //防止重复触发 if(this.isLoading){ return; } const query = uni.createSelectorQuery().in(this); query.select('#listArea').boundingClientRect(data => { let { height//listArea节点的高度 } = data; //若是设置的事件触发距离 大于等于 (节点的高度-屏幕高度-滚动条到顶部的距离) if(this.bottomDistinct>=height-this.screenHeight-scrollTop){ //阻止时间重复触发 this.isLoading=true; //模拟异步加载数据 uni.showToast({ title:"获取新数据" }) setTimeout(()=>{ //测试数据 let arr=new Array(5).fill(0); arr=arr.map((v,i)=>this.info.length+i+1); //数据填充 this.info=this.info.concat(arr); //恢复事件触发 this.isLoading=false; }, 1500); } }).exec(); } } } </script> <style> .text-area { display: flex; justify-content: center; flex-direction: column; align-items: center; background-color: #007AFF; } .square{ margin: 1em; background-color: #4CD964; color: #fff; width:8em; text-align: center; line-height: 5em; height: 5em; } </style>