选项卡数据后端提供,数量级较大,一屏显示不下。产品提供的解决方案是懒加载选项卡,在滚动到最后一条数据后,再次点击next按钮,便请求新的选项卡数据。项目用的element-ui,el-tab自动带有滚动按钮,是使用transform位移变换来实现的。这里主要是思考的其实是,如何合适的判断用户是否已经滚动到最后一条数据。
这里使用dom对象的getBoundingClientRect()方法,此函数返回一个Rect对象,其中有8个属性,如下:
利用最后一个选项卡dom节点的bottom属性值和其固定大小在页面中的父元素的bottom属性值作比较,若相等,则已经滚动到最后的选项卡节点,便触发请求新的选项卡数据。
// tabVNode为el-tab的vnode对象(可以使用Vue.$refs[]获取)
// data.items为选项卡数组,searchForm为请求选项卡数据时的请求体参数。
addTabEvent(tabVNode, data, searchForm){
// 给tab的next按钮添加点击事件,在数据到底时获取新数据
if(!tabVNode){
return ;
}
// 这里获取next按钮的dom节点,并且判断是否已经绑定click事件。
let nextDom = tabVNode.$children[0].$el.children[1];
if(nextDom && !nextDom.onclick){
nextDom.onclick = this.handleTabNext(tabVNode, data, searchForm);
}
},
handleTabNext(tabVNode, data, searchForm){
return () => {
// 获取固定大小的父元素的dom节点
const scrollDom = tabVNode.$children[0].$el.children[2];
// 获取最后一个选项卡的dom节点
const finalDom = tabVNode.$children[0].$el.children[2].children[0].lastChild;
let scrollDomRect = scrollDom.getBoundingClientRect();
let finalDomRect = finalDom.getBoundingClientRect();
/**
利用最后一个选项卡dom节点的bottom属性值和其固定大小在页面中的父元素的bottom属性值作比较。
若相等,则已经滚动到最后的选项卡节点,便触发请求新的选项卡数据。
*/
// 此处原本为全等判断。但是遇到了一个特殊的兼容性问题(文末细说),所以改为做差值小于10判断。
if(Math.abs(scrollDomRect.bottom - finalDomRect.bottom) <= 10){
if(data.items.length < data.total){
searchForm.pageIndex++;
this.getData(searchForm, true);
}else{
this.$message.info("已获取所有厂站");
}
}
}
},
兼容性问题:
本来判断bottom属性值是采用全等判断的,在不同分辨率的屏幕下都是可以兼容的。但是,windows提供了显示缩放功能,有100%,125%(默认),150%等缩放比例。我遇到的bug是,在1980*1080分辨率的屏幕上,默认的125%比例下时,原本应满足情况的两个bottom值相差了1px不到,我认为是缩放的问题,使分辨率计算有了精度丢失。所以这里给了10px的可允许误差值。