本文介绍如何在APP落地页使用Zepto.js实现滚动条监控与自动分页加载。通过计算contentH、viewH和scrollTop确定触底条件,解决iOS浏览器精度误差问题,并在加载下一页时同步发送埋点数据,确保用户体验与数据统计的准确性。
滚动加载需求与场景
需求:在APP落地页上的底部位置显示此前其他用户的购买记录,要求此div盒子只显示3条半,但一页有10条,div内的滑动条滑到一页底部自动加载下一页并发加载埋点。
核心概念与高度计算
实现原理:首先需要明确三个核心概念,即contentH(内容高度)、viewH(可视高度)以及scrollTop(滚动偏移量)。
contentH:指待滚动元素内容的总高度,涵盖可见部分及滚动条下方不可见的剩余部分。
ViewH:指当前DIV容器的可视高度,仅包含用户直接看到的区域,不包含滚动条下方的不可见部分。
scrollTop:指滚动条距离顶部的偏移距离。当scrollTop为0时,表示滚动条位于最顶端。拖动滚动条从顶至底,变化的是scrollTop的值。例如,若contentH为2000,而DIV高度(viewH)仅为300,则剩余1700为不可见区域。当滚动条拖至最底部时,scrollTop值为1700,这也可理解为滚动条可滚动的最大长度。触底时满足关系式:contentH = viewH + scrollTop。
基础实现逻辑
基于上述原理,可构建如下基础实现逻辑:
Ajax请求与数据加载
$.ajax({
type: "get",
url: "record.json",//测试用假数据
dataType: "json",
success: function (records) {
var showLength = records.data.length;//需要显示的总长度
var flag = showLength <= 10 ? showLength : 10;
load_records(0, flag);//开始加载第一页
hxmClickStat('mar_all_207_ssjk.goumai.load.' + 1, {url_ver: "SJCGBS-10030"});//不论长度是否超过10都发送第一页埋点
if (showLength > 10) {
var origin = 1, load = 2;
$('.records_body').scroll(function () {
var contentH = $(this).get(0).scrollHeight;
var viewH = $('.records_body').height();
var scrollTop = $(this).scrollTop();
var pages = Math.ceil(showLength / 10);//需要显示的总页数
if (viewH + scrollTop == contentH && load <= pages) {
if (load * 10 < showLength) {
load_records(origin++ * 10, load++ * 10);//加载下一页的10条数据
hxmClickStat('mar_all_207_ssjk.goumai.load.' + origin, {url_ver: "SJCGBS-10030"});//滑动到底部开始加载下一页时发送埋点
} else {
load_records(origin * 10, showLength);//加载最后一页
hxmScrollBottomStat('mar_all_207_ssjk.goumai.bottom', {url_ver: "SJCGBS-10030"});//最后一页发送埋点
load++;//避免重复执行
}
}
});
}
function load_records(start, end) {
for (var i = start; i < end; i++) {
var stime = records.data[i].time;
var accure_time = stime.slice(5, stime.length);
var record_html = '<div class="records_item"><img src=' + records.data[i].avatar + ' class="avatar"/><div class="buyer_info"><p class="buyer_name">' + records.data[i].account + '</p><p class="status_title">购买成功</p></div>\n\<' +
'div class="buyer_address"><p class="buy_address">' + records.data[i].city + ' IP:' + records.data[i].ip + '</p>\n\<' +
'p class="buy_time">' + accure_time + '</p></div></div>';
$(record_html).appendTo('.records_body');//插入一条购买记录
}
}
},
error: function () {
console.log('some errors happened!');
}
});
iOS浏览器适配与误差处理
上述基础方法在苹果手机浏览器中可能无法达到预期效果,需进行代码改进与适配。
改进方案:调整触底判断条件,增加容错机制。
修改后的判断逻辑为:if (viewH + scrollTop + 1 >= contentH && load <= pages)。
原因分析:通过打印滚动过程中的scrollTop、viewH和contentH数值,发现触底时存在1个单位的误差。这可能是由于部分DIV元素高度非整数,而JavaScript在判断时直接取整所致。因此,在判断条件中加1可解决此精度问题。
此外,也可采用百分比判断方式:当滚动条距离底端2%以内时,满足条件 scrollTop / (contentH - viewH) >= 0.98。
或者使用绝对数值范围判断:当滚动条距离底端30px以内时,满足条件 contentH - viewH - scrollTop <= 30。
以上即为基于Zepto.js实现滚动监控、自动加载及埋点上报的完整方案,希望能为相关开发工作提供参考。