From 35bc239d20240b49d157f4a9bc0218cd087e6b18 Mon Sep 17 00:00:00 2001 From: tank0317 Date: Tue, 28 May 2019 12:04:19 +0800 Subject: [PATCH] feat(scroll): optimise scroll pullup (#482) * feat(scroll): add pullUpLoad subprops visible * feat(scroll): enhance forceUpdate * chore(scroll): update docs and test * optimise(scroll): using nextElementSubling * chore(docs): update scroll doc * chore(unit): update unit test to improve coverage * chore: fix scroll docs --- document/components/docs/en-US/scroll.md | 15 +++--- document/components/docs/zh-CN/scroll.md | 16 +++--- src/components/scroll/scroll.vue | 68 +++++++++++++++++++----- test/unit/specs/scroll.spec.js | 7 +-- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/document/components/docs/en-US/scroll.md b/document/components/docs/en-US/scroll.md index 49dd90c9..11577354 100644 --- a/document/components/docs/en-US/scroll.md +++ b/document/components/docs/en-US/scroll.md @@ -441,6 +441,9 @@ In `options`, there are three frequently-used options, `scrollbar`、`pullDownRe | - | - | - | - | - | | threshold | the threshold of distance that pulling up for loading | Number | - | 0 | | txt | the text shown when pulling up loading | Object | - | { more: '', noMore: '' } | +| visible1.13.0 | txt visible or not when content is not more enough | Boolean | true/false | false | + +> When pullUpLoad is enabled and the content height is smaller than the container, by default, the copy `pullUpLoad.txt` needs to be pulled up to be seen. If you want to see the prompt copy without pulling up, you can set `pullUpLoad.visible` to `true`。 ### Slot @@ -466,9 +469,9 @@ In `options`, there are three frequently-used options, `scrollbar`、`pullDownRe | Method Name | Description | Parameters | | - | - | - | -| scrollTo | Scroll to specific position. | x: horizontal position
y: vertical position
time: transition time
ease: easing function | -| forceUpdate | Mark the end of pull-up or pull-down, and force recalculation of scrollable distance | dirty: whether there is data updating, when "true" indicate data updated so recalculate scrollable distance, when false no data update and no need to recalculate | -| disable | Disable scroll. | - | -| enable | Enable scroll. It's enabled by default | - | -| resetPullUpTxt | Reset pull up txt when pull up state changed from no data to data updated | - | -| refresh | Refresh, computed height and called BetterScroll instance's refresh | - | +| scrollTo(x, y, time, ease) | Scroll to specific position. | x: number, horizontal position
y: number, vertical position
time: number, transition time(ms)
ease: easingFn, easing function | +| forceUpdate(dirty, nomore) | Mark pull-up or pull-down end, force recalculation of scrollable distance | dirty: boolean, default to false, if true express has data update。
nomore: boolean, default to false, if true represent has no more data. When params nomore is true, when pullup shows the value of `pullUpLoad.txt.nomore`, but when dirty is false, nomore is invalid.| +| disable() | Disable scroll. | - | +| enable() | Enable scroll. It's enabled by default | - | +| resetPullUpTxt() | Reset pull up txt when pull up state changed from no data to data updated | - | +| refresh() | Refresh, computed height and called BetterScroll instance's refresh | - | diff --git a/document/components/docs/zh-CN/scroll.md b/document/components/docs/zh-CN/scroll.md index f88529dd..fc457ba6 100644 --- a/document/components/docs/zh-CN/scroll.md +++ b/document/components/docs/zh-CN/scroll.md @@ -442,6 +442,9 @@ | - | - | - | - | - | | threshold | 上拉刷新动作的上拉距离阈值 | Number | - | 0 | | txt | 上拉加载的相关文案 | Object | - | { more: '', noMore: '' } | +| visible1.13.0 | 内容不满一屏时,txt 文案是否可见 | Boolean | true/false | false | + +> 当开启 pullUpLoad,且内容较少,内容高度小于容器时,默认情况下,`pullUpLoad.txt` 配置的文案如“上滑加载更多”,需要上拉后才能看到。如果希望无需上拉即可看到提示文案,可以设置 `pullUpLoad.visible` 为 `true`。 ### 插槽 @@ -466,12 +469,13 @@ | 方法名 | 说明 | 参数 | | - | - | - | -| scrollTo | 滚动到指定位置 | x: 横向位置
y: 纵向位置
time: 过渡动画时间
ease: 动画曲线 | -| forceUpdate | 标记上拉下拉结束,强制重新计算可滚动距离 | dirty: 是否有数据更新,默认为 false。true 表示有数据更新重新计算可滚动距离,上拉文案显示`pullUpLoad.text.more`值,false 表示没有数据更新,无需重新计算, 上拉文案显示`pullUpLoad.text.nomore`值 | -| disable | 禁用滚动 | - | -| enable | 启用滚动,默认是开启滚动的。 | - | -| resetPullUpTxt | 当从无更多切换到有更多时,重置上拉文本内容 | - | -| refresh | 刷新,重新计算高度且刷新 BetterScroll 实例 | - | +| scrollTo(x, y, time, ease) | 滚动到指定位置 | x: number, 横向位置
y: number, 纵向位置
time: number, 过渡动画时间 (ms)
ease: EasingFn, 缓动曲线 | +| forceUpdate(dirty, nomore) | 标记上拉下拉结束,强制重新计算可滚动距离 | dirty: boolean, 标识有数据更新,默认为 false。
nomore: boolean, pullUpLoad 中标识没有更多数据,默认为 false。当 nomore 为 true 时,上拉加载展示 `pullUpLoad.txt.nomore` 值,但当 dirty 为 false 时,nomore 无效。| +| disable() | 禁用滚动 | - | +| enable() | 启用滚动,默认是开启滚动的。 | - | +| resetPullUpTxt() | 当从无更多切换到有更多时,重置上拉文本内容 | - | +| refresh() | 刷新,重新计算高度且刷新 BetterScroll 实例 | - | + ### 内部属性 diff --git a/src/components/scroll/scroll.vue b/src/components/scroll/scroll.vue index f2078917..e9b60be6 100644 --- a/src/components/scroll/scroll.vue +++ b/src/components/scroll/scroll.vue @@ -148,11 +148,12 @@ beforePullDown: true, isPullingDown: false, isPullUpLoad: false, - pullUpDirty: true, + pullUpNoMore: false, bubbleY: 0, pullDownStyle: '', pullDownStop: 40, - pullDownHeight: 60 + pullDownHeight: 60, + pullUpHeight: 0 } }, computed: { @@ -175,7 +176,7 @@ const moreTxt = (txt && txt.more) || '' const noMoreTxt = (txt && txt.noMore) || '' - return this.pullUpDirty ? moreTxt : noMoreTxt + return this.pullUpNoMore ? noMoreTxt : moreTxt }, refreshTxt() { const pullDownRefresh = this.pullDownRefresh @@ -206,14 +207,14 @@ this.scroll.openPullDown(newVal) if (!oldVal) { this._onPullDownRefresh() - this._calculateMinHeight() + this._pullDownRefreshChangeHandler() } } if (!newVal && oldVal) { this.scroll.closePullDown() this._offPullDownRefresh() - this._calculateMinHeight() + this._pullDownRefreshChangeHandler() } }, deep: true @@ -224,14 +225,14 @@ this.scroll.openPullUp(newVal) if (!oldVal) { this._onPullUpLoad() - this._calculateMinHeight() + this._pullUpLoadChangeHandler() } } if (!newVal && oldVal) { this.scroll.closePullUp() this._offPullUpLoad() - this._calculateMinHeight() + this._pullUpLoadChangeHandler() } }, deep: true @@ -273,12 +274,13 @@ this._listenScrollEvents() if (this.pullDownRefresh) { - this._getPullDownEleHeight() this._onPullDownRefresh() + this._pullDownRefreshChangeHandler() } if (this.pullUpLoad) { this._onPullUpLoad() + this._pullUpLoadChangeHandler() } }, disable() { @@ -304,7 +306,7 @@ clickItem(item) { this.$emit(EVENT_CLICK, item) }, - forceUpdate(dirty = false) { + forceUpdate(dirty = false, nomore = false) { if (this.pullDownRefresh && this.isPullingDown) { this.isPullingDown = false this._reboundPullDown(() => { @@ -313,14 +315,14 @@ } else if (this.pullUpLoad && this.isPullUpLoad) { this.isPullUpLoad = false this.scroll.finishPullUp() - this.pullUpDirty = dirty + this.pullUpNoMore = !dirty || nomore dirty && this.refresh() } else { dirty && this.refresh() } }, resetPullUpTxt() { - this.pullUpDirty = true + this.pullUpNoMore = false }, _listenScrollEvents() { this.finalScrollEvents.forEach((event) => { @@ -406,9 +408,22 @@ return reachBoundary }, _calculateMinHeight() { - if (this.$refs.listWrapper) { - this.$refs.listWrapper.style.minHeight = this.pullDownRefresh || this.pullUpLoad ? `${getRect(this.$refs.wrapper).height + 1}px` : 0 + const { wrapper, listWrapper } = this.$refs + const pullUpLoad = this.pullUpLoad + const pullDownRefresh = this.pullDownRefresh + let minHeight = 0 + + if (pullDownRefresh || pullUpLoad) { + const wrapperHeight = getRect(wrapper).height + minHeight = wrapperHeight + 1 + if (pullUpLoad && pullUpLoad.visible) { + // minHeight = wrapperHeight + 1 - pullUpHeight, then pullUpLoad text is visible + // when content's height is not larger than wrapper height + minHeight -= this.pullUpHeight + } } + + listWrapper.style.minHeight = `${minHeight}px` }, _onPullDownRefresh() { this.scroll.on('pullingDown', this._pullDownHandle) @@ -418,6 +433,12 @@ this.scroll.off('pullingDown', this._pullDownHandle) this.scroll.off('scroll', this._pullDownScrollHandle) }, + _pullDownRefreshChangeHandler() { + this.$nextTick(() => { + this._getPullDownEleHeight() + this._calculateMinHeight() + }) + }, _pullDownHandle() { if (this.resetPullDownTimer) { clearTimeout(this.resetPullDownTimer) @@ -435,6 +456,12 @@ this.pullDownStyle = `top:${Math.min(pos.y - this.pullDownStop, 0)}px` } }, + _pullUpLoadChangeHandler() { + this.$nextTick(() => { + this._getPullUpEleHeight() + this._calculateMinHeight() + }) + }, _onPullUpLoad() { this.scroll.on('pullingUp', this._pullUpHandle) }, @@ -460,7 +487,11 @@ }, this.scroll.options.bounceTime) }, _getPullDownEleHeight() { - const pulldown = this.$refs.pulldown.firstChild + let pulldown = this.$refs.pulldown + if (!pulldown) { + return + } + pulldown = pulldown.firstChild this.pullDownHeight = getRect(pulldown).height this.beforePullDown = false @@ -471,6 +502,15 @@ this.beforePullDown = true this.isPullingDown = false }) + }, + _getPullUpEleHeight() { + const listWrapper = this.$refs.listWrapper + const pullup = listWrapper.nextElementSibling + if (!pullup) { + this.pullUpHeight = 0 + return + } + this.pullUpHeight = getRect(pullup).height } }, components: { diff --git a/test/unit/specs/scroll.spec.js b/test/unit/specs/scroll.spec.js index 73295254..52e76d30 100644 --- a/test/unit/specs/scroll.spec.js +++ b/test/unit/specs/scroll.spec.js @@ -172,7 +172,8 @@ describe('Scroll', () => { txt: { more: 'more', noMore: 'noMore' - } + }, + visible: true } } }, @@ -203,11 +204,11 @@ describe('Scroll', () => { .to.be.callCount(1) // test: forceUpdate - vm.forceUpdate() + vm.forceUpdate(true, true) setTimeout(() => { expect(vm.isPullUpLoad).to.be.false - expect(vm.pullUpDirty).to.be.false + expect(vm.pullUpNoMore).to.be.true const pullUpTxtElm = vm.$el.querySelector('.cube-pullup-wrapper span') expect(pullUpTxtElm.textContent).to.equal('noMore') -- GitLab