设置div的overflow属性,可以使得该div具有滚动效果,下面以div中包含的是table来举例。
当table的元素较多,以至于超出div的显示范围的话,观察下该div元素的以下3个属性:
clientHeight是div的显示高度,scrollHeight是整个table的高度,scrollTop是上方溢出区高度,注意下,下方溢出高度没有直接的属性,需要计算得到,就是scrollHeight-clientHeight-scrollTop
有时候,我们在界面上不提供上一页、下一页这样的按钮,而是通过滚动(PC上通过鼠标滚动来实现,触摸屏通过手指在屏幕上滑动来实现)来加载前面或后面的数据,当向上滚动时如果上方溢出区高度小于某个阈值时加载前面的记录,当向下滚动时如果下方溢出区高度小于某个阈值时加载后面的记录。向后追加数据后,当前可视区域内容不会有变化,而向前插入数据的话,为了不影响可视区域内容,我们可以将scrollTop调整下高度,具体增大值为插入后的scrollHeight与插入前的scrollHeight之差。
从内存和性能方面考虑,html的table中元素应该有一个数量限制,不应该只允许添加而从不删除,所以可以在添加数据后进行判断,如果超限则执行删除,向前插入则删除最后的行,向后插入则删除最先的行。
有scroll事件,但是没有向上滚动或者向下滚动事件,滚动的方向是需要计算判断的,比如保存上次滚动时的scrollTop,跟当前的scrollTop进行比较,当前的大,则是向下滚动,当前的小,则是向上滚动。
这样基本完成了设计,但是仍有一些坑,一般数据的获取是从后端http异步调用得到,会花一些时间,而scroll的事件是浏览器前端触发,在数据获取期间,不应该继续向后端发起数据获取请求,每次数据获取完成时,再允许向后端发起数据获取请求,可以设置一个变量来标识是否在进行数据获取处理。还有一个可能遇到的坑,存在一定概率发生,当上次滚动事件完成时,可视区域正好停在滚动区域顶部或者底部,这时如果向上滚动或者向下滚动时,浏览器可能会屏蔽向上滚动事件发生或向下滚动事件发生。那么此时要不要采用其他方式来触发呢?可以的,此时不能只监听scoll事件了,对于鼠标滚动事件(wheel)要监听下,从事件的deltaY属性跟此前的值进行比较来判断是向上滚动还是向下滚动,或者对触屏的touchstart事件与touchmove事件进行监听,以判断是向上滑动还是向下滑动。参考代码如下:
<script>
// 监听 scroll 事件
window.addEventListener('scroll', function() {
console.log('Scroll event triggered, scrollTop:', document.documentElement.scrollTop);
});
// 监听 wheel 事件(鼠标滚轮或触摸板)
window.addEventListener('wheel', function(event) {
console.log('Wheel event triggered, deltaY:', event.deltaY);
});
// 监听 touchstart 和 touchmove 事件(触摸设备)
let startY = 0;
window.addEventListener('touchstart', function(event) {
startY = event.touches[0].clientY; // 记录触摸起始位置
});
window.addEventListener('touchmove', function(event) {
const currentY = event.touches[0].clientY; // 获取当前触摸位置
const deltaY = currentY - startY; // 计算滑动距离
console.log('Touchmove event triggered, deltaY:', deltaY);
});
</script>