开发使用vant的list组件时,会自动加载数据。网上查阅了资料,有以下处理方案:
1. 保证父级至根元素没有overflow-y: scroll属性
2. list组件设置 height: xxx; overflow: scroll;
根据第一点,代码样式中并没有overflow-y: scroll。根据第二点,可以实现,但业务不需要设置列表的高度,故不适用(可以动态计算,看上去列表是铺满页面的)
因为网上没有比较合理的解释,所以看了一下list源码,是如何实现监听滚动到底部的(结果请看移步到最后)
## 查阅list组件,滚动时调用check方法判定是否加载
if (direction === 'up') { isReachEdge = scrollerRect.top - placeholderRect.top <= offset;} else {
// 默认走这边 isReachEdge = placeholderRect.bottom - scrollerRect.bottom <= offset;}
根据以上代码,可以知道placeholderRect和scrollerRect是主要判定是否滚动的主要元素。
placeholderRect
var placeholderRect = _this.$refs.placeholder.getBoundingClientRect();
可以明显看出,这个元素属于list组件,打印一下可以知道这是list组件最下边的一个占位符
scrollerRect
var el = _this.$el, scroller = _this.scroller;var scrollerRect;if (scroller.getBoundingClientRect) {
scrollerRect = scroller.getBoundingClientRect();} else { scrollerRect = { top: 0, bottom: scroller.innerHeight };}
根据以上代码块可得出,scrollerRect值是由scroller决定得,并且scroller有两种情况。那咱就继续看scroller吧。
export default createComponent({
mixins: [BindEventMixin(function (bind) { if (!this.scroller) { this.scroller = getScroller(this.$el); } bind(this.scroller, 'scroll', this.check); })],})
BindEventMixin做了事件的绑定和销毁,咱们这里主要看getScroller方法
var overflowScrollReg = /scroll|auto/i;
export function getScroller(el, root) {
// 因为调用时没传入root,故默认元素为window if (root === void 0) { root = window; } var node = el;
// 从传入元素开始向上遍历,找到元素样式overflow-Y为scroll或者auto时,返回 while (node && node.tagName !== 'HTML' && node.tagName !== 'BODY' && node.nodeType === 1 && node !== root) { var _window$getComputedSt = window.getComputedStyle(node), overflowY = _window$getComputedSt.overflowY; console.log(22, node, _window$getComputedSt) if (overflowScrollReg.test(overflowY)) { return node; } node = node.parentNode; }
return root;}
现在知道scroller出现的两种情况了:
1. list组件从自身向上层遍历,知道找到某个元素的overflow-y为scroll或者auto时返回
2. 上面条件不符合,返回传入的元素root(这里默认是window)
根据以上两种情况,继续1回来分析
isReachEdge = placeholderRect.bottom - scrollerRect.bottom <= offset;
当scroller符合条件2时,scrollerRect.bottom 为当前窗口显示区域的高度,这样是可以计算出来的
当scroller符合条件1时,scrollerRect.bottom 为符合元素底部距离窗口顶部的距离,这样也是可以计算出来的
那么咱们无限触发是怎么产生的呢?
条件1除了元素需要overflow-y为scroll或者auto之外,还需要给定高度!最终咱们总结了两种使用场景:
条件1适用场景为,用户想在指定高度的元素中使用list组件(height: xxx; overflow-y: scroll | auto;)
条件2适用场景为,用户想简单使用列表,铺满屏幕(保证父级至根元素没有overflow-y: scroll | auto)
至此本次问题就分析完毕,大家可以根据场景自由发挥。
然而,我想使用条件2,并且父级至根元素没有overflow-y: scroll | auto,还是会自动加载!!!最后用源码debug发现,父级给了 overflow-x: hidden之后,overflow-y变为了auto, 又学到了!