You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
consthandleScroll=function(cb){const{ el, vm, container, observer }=this[scope];const{ distance, disabled }=getScrollOptions(el,vm);if(disabled)return;constcontainerInfo=container.getBoundingClientRect();if(!containerInfo.width&&!containerInfo.height)return;letshouldTrigger=false;if(container===el){// be aware of difference between clientHeight & offsetHeight & window.getComputedStyle().heightconstscrollBottom=container.scrollTop+getClientHeight(container);shouldTrigger=container.scrollHeight-scrollBottom<=distance;}else{constheightBelowTop=getOffsetHeight(el)+getElementTop(el)-getElementTop(container);constoffsetHeight=getOffsetHeight(container);constborderBottom=Number.parseFloat(getStyleComputedProperty(container,'borderBottomWidth'));shouldTrigger=heightBelowTop-offsetHeight+borderBottom<=distance;}if(shouldTrigger&&isFunction(cb)){cb.call(vm);}elseif(observer){observer.disconnect();this[scope].observer=null;}};
InfiniteScroll 无限滚动,也就是滚动到底部时,加载更多的数据。
实现原理
无限滚动的原理就是,用户滚动,当滚动条到底的时候就加载。所以很关键的一点是要知道滚动条和底部的距离。
先了解三个概念:
通过计算就可以的得到滚动条到底部的距离:
element 的 InfiniteScroll 无限滚动
可以试一下如何使用 InfiniteScroll,然后 element 的源码是怎么实现的:
通过指令的方式来实现的,
inserted
钩子在被绑定元素插入父节点时调用,首先通过const container = getScrollContainer(el, true);
获取滚动的元素,这个方法定义在element-ui/src/utils/dom
:从该元素开始循环判断父元素是否定义了
overflow
样式,来确定滚动容器container
。接下来就会监听滚动容器的滚动事件。滚动的时候就执行
onScroll
方法,为了优化性能,这个方法是节流函数throttle
执行之后返回的,所以实际上执行的是handleScroll
。这个等会再分析。先看下面的代码对
immediate
的判断,如果是true
,即立即执行,则创建一个new MutationObserver(onScroll)
实例,并监听容器,内容改变之后会执行回调函数onScroll
。为什么这么处理呢?
因为无限滚动是通过滚动加载实现的,如果初始状态下内容无法撑满容器,就无法出现滚动条,那就会造成后面无法滚动加载数据了!这个默认就是
true
,保证加载到出现滚动条。handleScroll
的实现如下:看一下主要流程,首先会判断
disabled
,如果是true
直接返回。可以结合官方实例,实际开发中,如果正在加载数据,那么就可以将disabled
设置为true
,避免多次触发。根据容器不同,判断方法有些差异:
判断是否已经到底部了。这里是判断是否小于等于
distance
,它提供了一个配置项,距离底部distance
的时候就可以触发回调了。当鼠标往下滚的时候,
el
就会向上,heightBelowTop - offsetHeight + borderBottom
其实就是el
底部到container
的距离,它和distance
含义其实是一样的。如果满足条件就会执行回调
cb.call(vm)
。同时,上面说过设置immediate
会立即加载,加载完成之后移除observer
。参考
The text was updated successfully, but these errors were encountered: