fix: virtual list error at firefox, close #6470

pull/6490/head
tangjinzhou 2 years ago
parent c690f4188a
commit 78c8c9d791

@ -226,8 +226,13 @@ const List = defineComponent({
offset: undefined, offset: undefined,
}); });
} }
if (componentRef.value) {
state.scrollTop = componentRef.value.scrollTop;
}
},
{
immediate: true,
}, },
{ immediate: true },
); );
watch( watch(
[ [
@ -277,11 +282,11 @@ const List = defineComponent({
itemTop = currentItemBottom; itemTop = currentItemBottom;
} }
// Fallback to normal if not match. This code should never reach // When scrollTop at the end but data cut to small count will reach this
/* istanbul ignore next */
if (startIndex === undefined) { if (startIndex === undefined) {
startIndex = 0; startIndex = 0;
startOffset = 0; startOffset = 0;
endIndex = Math.ceil(height / itemHeight);
} }
if (endIndex === undefined) { if (endIndex === undefined) {
endIndex = dataLen - 1; endIndex = dataLen - 1;
@ -325,7 +330,7 @@ const List = defineComponent({
// When data size reduce. It may trigger native scroll event back to fit scroll position // When data size reduce. It may trigger native scroll event back to fit scroll position
function onFallbackScroll(e: UIEvent) { function onFallbackScroll(e: UIEvent) {
const { scrollTop: newScrollTop } = e.currentTarget as Element; const { scrollTop: newScrollTop } = e.currentTarget as Element;
if (Math.abs(newScrollTop - state.scrollTop) >= 1) { if (newScrollTop !== state.scrollTop) {
syncScrollTop(newScrollTop); syncScrollTop(newScrollTop);
} }

@ -119,6 +119,7 @@ export default defineComponent({
this.onScrollbarTouchStart, this.onScrollbarTouchStart,
supportsPassive ? ({ passive: false } as EventListenerOptions) : false, supportsPassive ? ({ passive: false } as EventListenerOptions) : false,
); );
if (this.thumbRef.current) {
this.thumbRef.current.removeEventListener( this.thumbRef.current.removeEventListener(
'touchstart', 'touchstart',
this.onMouseDown, this.onMouseDown,
@ -130,7 +131,7 @@ export default defineComponent({
supportsPassive ? ({ passive: false } as EventListenerOptions) : false, supportsPassive ? ({ passive: false } as EventListenerOptions) : false,
); );
this.thumbRef.current.removeEventListener('touchend', this.onMouseUp); this.thumbRef.current.removeEventListener('touchend', this.onMouseUp);
}
raf.cancel(this.moveRaf); raf.cancel(this.moveRaf);
}, },

@ -1,6 +1,7 @@
import type { VNodeProps, Ref, ShallowRef } from 'vue'; import type { VNodeProps, Ref, ShallowRef } from 'vue';
import { watch, ref } from 'vue'; import { onUnmounted, watch, ref } from 'vue';
import type { GetKey } from '../interface'; import type { GetKey } from '../interface';
import wrapperRaf from '../../_util/raf';
export type CacheMap = Map<any, number>; export type CacheMap = Map<any, number>;
@ -16,14 +17,14 @@ export default function useHeights<T>(
watch(mergedData, () => { watch(mergedData, () => {
updatedMark.value = Symbol('update'); updatedMark.value = Symbol('update');
}); });
let heightUpdateId = 0; let collectRaf: number = undefined;
function cancelRaf() {
wrapperRaf.cancel(collectRaf);
}
function collectHeight() { function collectHeight() {
heightUpdateId += 1; cancelRaf();
const currentId = heightUpdateId; collectRaf = wrapperRaf(() => {
Promise.resolve().then(() => {
// Only collect when it's latest call
if (currentId !== heightUpdateId) return;
// let changed = false;
instance.forEach((element, key) => { instance.forEach((element, key) => {
if (element && element.offsetParent) { if (element && element.offsetParent) {
const { offsetHeight } = element; const { offsetHeight } = element;
@ -57,6 +58,9 @@ export default function useHeights<T>(
} }
} }
} }
onUnmounted(() => {
cancelRaf();
});
return [setInstance, collectHeight, heights, updatedMark]; return [setInstance, collectHeight, heights, updatedMark];
} }

@ -103,7 +103,7 @@ export default function useScrollTo(
collectHeight(); collectHeight();
} }
syncScroll(times - 1, newTargetAlign); syncScroll(times - 1, newTargetAlign);
}); }, 2);
}; };
syncScroll(5); syncScroll(5);

Loading…
Cancel
Save