|
@@ -14,35 +14,27 @@
|
|
|
<view class="nut-infinite-bottom">
|
|
<view class="nut-infinite-bottom">
|
|
|
<template v-if="isInfiniting">
|
|
<template v-if="isInfiniting">
|
|
|
<view class="bottom-box">
|
|
<view class="bottom-box">
|
|
|
- <template v-if="!slots.loading">
|
|
|
|
|
|
|
+ <slot name="loading">
|
|
|
<nut-icon class="bottom-img" v-bind="$attrs" :name="loadIcon"></nut-icon>
|
|
<nut-icon class="bottom-img" v-bind="$attrs" :name="loadIcon"></nut-icon>
|
|
|
<view class="bottom-text">{{ loadTxt || translate('loading') }}</view>
|
|
<view class="bottom-text">{{ loadTxt || translate('loading') }}</view>
|
|
|
- </template>
|
|
|
|
|
- <slot name="loading" v-else></slot>
|
|
|
|
|
|
|
+ </slot>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
<template v-else-if="!hasMore">
|
|
<template v-else-if="!hasMore">
|
|
|
- <view class="tips" v-if="!slots.finished">{{ loadMoreTxt || translate('loadMoreTxt') }}</view>
|
|
|
|
|
- <slot name="finished" v-else></slot>
|
|
|
|
|
|
|
+ <slot name="finished">
|
|
|
|
|
+ <view class="tips">{{ loadMoreTxt || translate('loadMoreTxt') }}</view>
|
|
|
|
|
+ </slot>
|
|
|
</template>
|
|
</template>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
<script lang="ts">
|
|
<script lang="ts">
|
|
|
-import {
|
|
|
|
|
- toRefs,
|
|
|
|
|
- onMounted,
|
|
|
|
|
- onUnmounted,
|
|
|
|
|
- reactive,
|
|
|
|
|
- computed,
|
|
|
|
|
- CSSProperties,
|
|
|
|
|
- onActivated,
|
|
|
|
|
- onDeactivated,
|
|
|
|
|
- ref
|
|
|
|
|
-} from 'vue';
|
|
|
|
|
|
|
+import { toRefs, onMounted, onUnmounted, reactive, computed, onActivated, onDeactivated, ref } from 'vue';
|
|
|
import { createComponent } from '@/packages/utils/create';
|
|
import { createComponent } from '@/packages/utils/create';
|
|
|
const { componentName, create, translate } = createComponent('infiniteloading');
|
|
const { componentName, create, translate } = createComponent('infiniteloading');
|
|
|
import { useTouch } from '@/packages/utils/useTouch';
|
|
import { useTouch } from '@/packages/utils/useTouch';
|
|
|
|
|
+import requestAniFrame from '@/packages/utils/raf';
|
|
|
|
|
+import { getScrollTopRoot } from '@/packages/utils/util';
|
|
|
|
|
|
|
|
export default create({
|
|
export default create({
|
|
|
props: {
|
|
props: {
|
|
@@ -116,31 +108,12 @@ export default create({
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const getStyle = computed(() => {
|
|
const getStyle = computed(() => {
|
|
|
- const style: CSSProperties = {};
|
|
|
|
|
return {
|
|
return {
|
|
|
height: state.distance < 0 ? `0px` : `${state.distance}px`,
|
|
height: state.distance < 0 ? `0px` : `${state.distance}px`,
|
|
|
- transition: state.isTouching
|
|
|
|
|
- ? `height 0s cubic-bezier(0.25,0.1,0.25,1)`
|
|
|
|
|
- : `height 0.2s cubic-bezier(0.25,0.1,0.25,1)`
|
|
|
|
|
|
|
+ transitionDuration: state.isTouching ? 0 : `0.2s`
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- const requestAniFrame = () => {
|
|
|
|
|
- return (
|
|
|
|
|
- window.requestAnimationFrame ||
|
|
|
|
|
- window.webkitRequestAnimationFrame ||
|
|
|
|
|
- function (callback) {
|
|
|
|
|
- window.setTimeout(callback, 1000 / 60);
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const getWindowScrollTop = () => {
|
|
|
|
|
- return window.pageYOffset !== undefined
|
|
|
|
|
- ? window.pageYOffset
|
|
|
|
|
- : (document.documentElement || document.body.parentNode || document.body).scrollTop;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
const calculateTopPosition = (el: HTMLElement): number => {
|
|
const calculateTopPosition = (el: HTMLElement): number => {
|
|
|
return !el ? 0 : el.offsetTop + calculateTopPosition(el.offsetParent as HTMLElement);
|
|
return !el ? 0 : el.offsetTop + calculateTopPosition(el.offsetParent as HTMLElement);
|
|
|
};
|
|
};
|
|
@@ -149,8 +122,9 @@ export default create({
|
|
|
let offsetDistance = 0;
|
|
let offsetDistance = 0;
|
|
|
let resScrollTop = 0;
|
|
let resScrollTop = 0;
|
|
|
let direction = 'down';
|
|
let direction = 'down';
|
|
|
- const windowScrollTop = getWindowScrollTop();
|
|
|
|
|
|
|
+
|
|
|
if (props.useWindow) {
|
|
if (props.useWindow) {
|
|
|
|
|
+ const windowScrollTop = getScrollTopRoot();
|
|
|
if (state.scroller) {
|
|
if (state.scroller) {
|
|
|
offsetDistance =
|
|
offsetDistance =
|
|
|
calculateTopPosition(state.scroller) + state.scroller.offsetHeight - windowScrollTop - window.innerHeight;
|
|
calculateTopPosition(state.scroller) + state.scroller.offsetHeight - windowScrollTop - window.innerHeight;
|
|
@@ -181,7 +155,7 @@ export default create({
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const handleScroll = () => {
|
|
const handleScroll = () => {
|
|
|
- requestAniFrame()(() => {
|
|
|
|
|
|
|
+ requestAniFrame(() => {
|
|
|
if (!isScrollAtBottom() || !props.hasMore || state.isInfiniting) {
|
|
if (!isScrollAtBottom() || !props.hasMore || state.isInfiniting) {
|
|
|
return false;
|
|
return false;
|
|
|
} else {
|
|
} else {
|
|
@@ -245,17 +219,19 @@ export default create({
|
|
|
return !!props.containerId ? document.querySelector(`#${props.containerId}`) : el && el.parentNode;
|
|
return !!props.containerId ? document.querySelector(`#${props.containerId}`) : el && el.parentNode;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ const removeScrollListener = () => {
|
|
|
|
|
+ state.scrollEl.removeEventListener('scroll', handleScroll, props.useCapture);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
const parentElement = getParentElement(state.scroller as HTMLElement) as Node & ParentNode;
|
|
const parentElement = getParentElement(state.scroller as HTMLElement) as Node & ParentNode;
|
|
|
state.scrollEl = props.useWindow ? window : parentElement;
|
|
state.scrollEl = props.useWindow ? window : parentElement;
|
|
|
|
|
|
|
|
scrollListener();
|
|
scrollListener();
|
|
|
-
|
|
|
|
|
- console.log(slots);
|
|
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
- state.scrollEl.removeEventListener('scroll', handleScroll, props.useCapture);
|
|
|
|
|
|
|
+ removeScrollListener();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const isKeepAlive = ref(false);
|
|
const isKeepAlive = ref(false);
|
|
@@ -269,7 +245,7 @@ export default create({
|
|
|
|
|
|
|
|
onDeactivated(() => {
|
|
onDeactivated(() => {
|
|
|
isKeepAlive.value = true;
|
|
isKeepAlive.value = true;
|
|
|
- state.scrollEl.removeEventListener('scroll', handleScroll, props.useCapture);
|
|
|
|
|
|
|
+ removeScrollListener();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
return {
|