checkBottomReached() { if (this.scrollEventTarget === window) { return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight; } else { return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1; } }
经过我的测试,上面的代码是有问题:
当scrollEventTarget是window的条件下,上面的判断是不对的。因为document.body.scrollTop总是比正常值小1,所以用于无法满足到达底部的条件;
当scrollEventTarget不是window的条件下,上面的判断条件也不需要在this.scrollEventTarget.getBoundingClientRect().bottom后面加1,但是加1也不会有太大视觉上的影响。
最后来看下moveend事件回调的处理函数
handleTouchEnd() { if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate > 0) { this.topDropped = true; // 为当前组件添加 is-dropped class(也就是添加动画处理) if (this.topStatus === 'drop') { // 到达了loading的状态 this.translate = '50'; // top slot的高度 this.topStatus = 'loading'; this.topMethod(); // 执行回调函数 } else { // 没有到达,回调原点 this.translate = '0'; this.topStatus = 'pull'; } } // 处理逻辑同上 if (this.direction === 'up' && this.bottomReached && this.translate < 0) { this.bottomDropped = true; this.bottomReached = false; if (this.bottomStatus === 'drop') { this.translate = '-50'; this.bottomStatus = 'loading'; this.bottomMethod(); } else { this.translate = '0'; this.bottomStatus = 'pull'; } } this.$emit('translate-change', this.translate); this.direction = ''; } }
总结
下拉刷新和上拉加载更多的实现原理可以借鉴
getScrollEventTarget()获取滚动对象,getScrollTop()获取滚动距离,checkBottomReached()判断是否滚动到底部;这三种方式可以借鉴
缺点: 写死了top slot 和 bottom slot的高度,太不灵活;这个地方可以优化