Skip to content

Commit 8db8fae

Browse files
committed
Add transition and stagger support
1 parent 00d5656 commit 8db8fae

File tree

1 file changed

+57
-11
lines changed

1 file changed

+57
-11
lines changed

src/components/InfiniteLoading.vue

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div class="infinite-loading-container">
33
<slot name="spinner">
4-
<i :class="spinnerType" v-show="isLoading"></i>
4+
<i :class="spinnerType" v-show="isLoading && !isTransitioning"></i>
55
</slot>
66
<div class="infinite-status-prompt" v-show="!isLoading && isComplete && isFirstLoad">
77
<slot name="no-results">No results :(</slot>
@@ -62,6 +62,8 @@
6262
isLoading: false,
6363
isComplete: false,
6464
isFirstLoad: true, // save the current loading whether it is the first loading
65+
isTransitioning: false, // save transition status
66+
loadedCount: 0,
6567
};
6668
},
6769
computed: {
@@ -79,6 +81,13 @@
7981
required: true,
8082
},
8183
spinner: String,
84+
transition: {
85+
type: Object, // Must be a Vue transition object
86+
},
87+
staggerCount: {
88+
type: Number,
89+
default: null,
90+
},
8291
},
8392
ready() {
8493
this.scrollParent = getScrollParent(this.$el);
@@ -94,22 +103,59 @@
94103
setTimeout(this.scrollHandler, 1);
95104
this.scrollParent.addEventListener('scroll', this.scrollHandler);
96105
},
106+
methods: {
107+
listenTransitionEndOnce(callback, isReset = false) {
108+
if (this.transition) {
109+
const type = isReset ? 'afterLeave' : 'afterEnter';
110+
const originalListener = this.transition[type];
111+
let staggerIndex = 0;
112+
113+
this.isTransitioning = true;
114+
this.transition[type] = () => {
115+
// has no stagger or complete all stagger
116+
if (this.staggerCount === null ||
117+
++staggerIndex === Math.abs(this.staggerCount - this.loadedCount)) {
118+
// restore original hook
119+
if (typeof originalListener === 'function') {
120+
originalListener.call(this);
121+
this.transition[type] = originalListener;
122+
} else {
123+
delete this.transition[type];
124+
}
125+
this.loadedCount = this.staggerCount; // save current count
126+
this.isTransitioning = false;
127+
callback.call(this);
128+
} else if (typeof originalListener === 'function') {
129+
originalListener.call(this);
130+
}
131+
};
132+
} else {
133+
callback.call(this);
134+
}
135+
},
136+
},
97137
events: {
98138
'$InfiniteLoading:loaded': function loaded() {
99-
this.isLoading = false;
100-
this.isFirstLoad = false;
139+
this.listenTransitionEndOnce(() => {
140+
this.isLoading = false;
141+
this.isFirstLoad = false;
142+
});
101143
},
102144
'$InfiniteLoading:complete': function complete() {
103-
this.isLoading = false;
104-
this.isComplete = true;
105-
this.scrollParent.removeEventListener('scroll', this.scrollHandler);
145+
this.listenTransitionEndOnce(() => {
146+
this.isLoading = false;
147+
this.isComplete = true;
148+
this.scrollParent.removeEventListener('scroll', this.scrollHandler);
149+
});
106150
},
107151
'$InfiniteLoading:reset': function reset() {
108-
this.isLoading = false;
109-
this.isComplete = false;
110-
this.isFirstLoad = true;
111-
this.scrollParent.addEventListener('scroll', this.scrollHandler);
112-
setTimeout(this.scrollHandler, 1);
152+
this.listenTransitionEndOnce(() => {
153+
this.isLoading = false;
154+
this.isComplete = false;
155+
this.isFirstLoad = true;
156+
this.scrollParent.addEventListener('scroll', this.scrollHandler);
157+
setTimeout(this.scrollHandler, 1);
158+
}, true);
113159
},
114160
},
115161
destroyed() {

0 commit comments

Comments
 (0)