Skip to content

Commit a25fcf6

Browse files
committed
Add force-use-infinite-wrapper support and throw warning when be in an infinite loop #55
1 parent ec2580f commit a25fcf6

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

src/components/InfiniteLoading.vue

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
<script>
1717
/* eslint-disable no-console */
1818
19+
const LOOP_CHECK_TIMEOUT = 1000; // the timeout for check infinite loop
20+
const LOOP_CHECK_MAX_CALLS = 10; // the maximum number of continuous calls
1921
const SPINNERS = {
2022
BUBBLES: 'loading-bubbles',
2123
CIRCLES: 'loading-circles',
@@ -47,6 +49,20 @@
4749
].join('\n'),
4850
INFINITE_EVENT: '[Vue-infinite-loading warn]: `:on-infinite` property will be deprecated soon, please use `@infinite` event instead.',
4951
};
52+
const ERRORS = {
53+
INFINITE_LOOP: [
54+
`[Vue-infinite-loading error]: executed the callback function more than ${LOOP_CHECK_MAX_CALLS} times for a short time, it looks like searched a wrong scroll wrapper that doest not has fixed height or maximum height, please check it. If you want to force to set a element as scroll wrapper ranther than automatic searching, you can do this:`,
55+
`
56+
<!-- add a special attribute for the real scroll wrapper -->
57+
<div infinite-wrapper>
58+
...
59+
<!-- set force-use-infinite-wrapper to true -->
60+
<infinite-loading force-use-infinite-wrapper="true"></infinite-loading>
61+
</div>
62+
`,
63+
'more details: https://github.com/PeachScript/vue-infinite-loading/issues/55#issuecomment-316934169',
64+
].join('\n'),
65+
};
5066
5167
export default {
5268
data() {
@@ -58,6 +74,9 @@
5874
isFirstLoad: true, // save the current loading whether it is the first loading
5975
debounceTimer: null,
6076
debounceDuration: 100,
77+
infiniteLoopChecked: false, // save the status of infinite loop check
78+
infiniteLoopTimer: null,
79+
continuousCallTimes: 0,
6180
};
6281
},
6382
computed: {
@@ -94,6 +113,7 @@
94113
type: String,
95114
default: 'bottom',
96115
},
116+
forceUseInfiniteWrapper: null,
97117
},
98118
mounted() {
99119
this.scrollParent = this.getScrollParent();
@@ -117,7 +137,7 @@
117137
this.isFirstLoad = false;
118138
119139
if (this.isLoading) {
120-
this.$nextTick(this.attemptLoad);
140+
this.$nextTick(this.attemptLoad.bind(null, true));
121141
}
122142
123143
if (!ev || ev.target !== this) {
@@ -181,8 +201,11 @@
181201
methods: {
182202
/**
183203
* attempt trigger load
204+
* @param {Boolean} isContinuousCall the flag of continuous call, it will be true
205+
* if this method be called in the `loaded`
206+
* event handler
184207
*/
185-
attemptLoad() {
208+
attemptLoad(isContinuousCall) {
186209
const currentDistance = this.getCurrentDistance();
187210
188211
if (!this.isComplete && currentDistance <= this.distance) {
@@ -193,6 +216,23 @@
193216
} else {
194217
this.$emit('infinite', this.stateChanger);
195218
}
219+
220+
if (isContinuousCall && !this.forceUseInfiniteWrapper && !this.infiniteLoopChecked) {
221+
// check this component whether be in an infinite loop if it is not checked
222+
// more details: https://github.com/PeachScript/vue-infinite-loading/issues/55#issuecomment-316934169
223+
this.continuousCallTimes += 1; // save the times of calls
224+
225+
clearTimeout(this.infiniteLoopTimer);
226+
this.infiniteLoopTimer = setTimeout(() => {
227+
this.infiniteLoopChecked = true;
228+
}, LOOP_CHECK_TIMEOUT);
229+
230+
// throw warning if the times of continuous calls large than the maximum times
231+
if (this.continuousCallTimes > LOOP_CHECK_MAX_CALLS) {
232+
console.error(ERRORS.INFINITE_LOOP);
233+
this.infiniteLoopChecked = true;
234+
}
235+
}
196236
} else {
197237
this.isLoading = false;
198238
}
@@ -229,7 +269,7 @@
229269
230270
if (elm.tagName === 'BODY') {
231271
result = window;
232-
} else if (['scroll', 'auto'].indexOf(getComputedStyle(elm).overflowY) > -1) {
272+
} else if (!this.forceUseInfiniteWrapper && ['scroll', 'auto'].indexOf(getComputedStyle(elm).overflowY) > -1) {
233273
result = elm;
234274
} else if (elm.hasAttribute('infinite-wrapper') || elm.hasAttribute('data-infinite-wrapper')) {
235275
result = elm;

0 commit comments

Comments
 (0)