Skip to content

Commit d2c41e2

Browse files
committed
feat: support restore scroll height when using top direction
1 parent 9e64820 commit d2c41e2

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/components/InfiniteLoading.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import Spinner from './Spinner.vue';
4242
import config, { evt3rdArg, WARNINGS, STATUS } from '../config';
4343
import {
44-
warn, throttleer, loopTracker, isBlankSlotElm,
44+
warn, throttleer, loopTracker, isBlankSlotElm, scrollBarStorage,
4545
} from '../utils';
4646
4747
export default {
@@ -133,6 +133,13 @@ export default {
133133
this.$on('$InfiniteLoading:loaded', (ev) => {
134134
this.isFirstLoad = false;
135135
136+
if (this.direction === 'top') {
137+
// wait for DOM updated
138+
this.$nextTick(() => {
139+
scrollBarStorage.restore(this.scrollParent);
140+
});
141+
}
142+
136143
if (this.status === STATUS.LOADING) {
137144
this.$nextTick(this.attemptLoad.bind(null, true));
138145
}
@@ -161,6 +168,7 @@ export default {
161168
this.status = STATUS.READY;
162169
this.isFirstLoad = true;
163170
throttleer.reset();
171+
scrollBarStorage.remove(this.scrollParent);
164172
this.scrollParent.addEventListener('scroll', this.scrollHandler, evt3rdArg);
165173
setTimeout(this.scrollHandler, 1);
166174
@@ -222,6 +230,13 @@ export default {
222230
) {
223231
this.status = STATUS.LOADING;
224232
233+
if (this.direction === 'top') {
234+
// wait for spinner display
235+
this.$nextTick(() => {
236+
scrollBarStorage.save(this.scrollParent);
237+
});
238+
}
239+
225240
if (typeof this.onInfinite === 'function') {
226241
this.onInfinite.call(null, this.stateChanger);
227242
} else {
@@ -287,6 +302,8 @@ export default {
287302
destroyed() {
288303
/* istanbul ignore else */
289304
if (!this.status !== STATUS.COMPLETE) {
305+
throttleer.reset();
306+
scrollBarStorage.remove(this.scrollParent);
290307
this.scrollParent.removeEventListener('scroll', this.scrollHandler, evt3rdArg);
291308
}
292309
},

src/utils.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,35 @@ export const loopTracker = {
5959
},
6060
};
6161

62+
export const scrollBarStorage = {
63+
key: '_infiniteScrollHeight',
64+
getScrollElm(elm) {
65+
return elm === window ? document.documentElement : elm;
66+
},
67+
save(elm) {
68+
const target = this.getScrollElm(elm);
69+
70+
// save scroll height on the scroll parent
71+
target[this.key] = target.scrollHeight;
72+
},
73+
restore(elm) {
74+
const target = this.getScrollElm(elm);
75+
76+
/* istanbul ignore else */
77+
if (typeof target[this.key] === 'number') {
78+
target.scrollTop = target.scrollHeight - target[this.key] + target.scrollTop;
79+
}
80+
81+
this.remove(target);
82+
},
83+
remove(elm) {
84+
if (elm[this.key] !== undefined) {
85+
// remove scroll height
86+
delete elm[this.key]; // eslint-disable-line no-param-reassign
87+
}
88+
},
89+
};
90+
6291
/**
6392
* determine slot is or not a empty element
6493
* @param {Slot} slot target slot
@@ -79,4 +108,5 @@ export default {
79108
throttleer,
80109
loopTracker,
81110
isBlankSlotElm,
111+
scrollBarStorage,
82112
};

0 commit comments

Comments
 (0)