fix: scroll error
parent
0de3e6b716
commit
c579bb0ad5
|
@ -3,12 +3,11 @@ import Item from './Item';
|
|||
import ScrollBar from './ScrollBar';
|
||||
import useHeights from './hooks/useHeights';
|
||||
import useScrollTo from './hooks/useScrollTo';
|
||||
// import useDiffItem from './hooks/useDiffItem';
|
||||
import useFrameWheel from './hooks/useFrameWheel';
|
||||
import useMobileTouchMove from './hooks/useMobileTouchMove';
|
||||
import useOriginScroll from './hooks/useOriginScroll';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { computed, nextTick, reactive, ref, watchEffect } from 'vue';
|
||||
import { computed, nextTick, reactive, watchEffect } from 'vue';
|
||||
import classNames from '../_util/classNames';
|
||||
import createRef from '../_util/createRef';
|
||||
|
||||
|
@ -40,7 +39,7 @@ const ListProps = {
|
|||
height: PropTypes.number,
|
||||
itemHeight: PropTypes.number,
|
||||
/** If not match virtual scroll condition, Set List still use height of container. */
|
||||
fullHeight: PropTypes.bool,
|
||||
fullHeight: PropTypes.bool.def(true),
|
||||
itemKey: PropTypes.any,
|
||||
component: PropTypes.any,
|
||||
/** Set `false` will always use real scroll instead of virtual one */
|
||||
|
@ -92,17 +91,12 @@ const List = {
|
|||
|
||||
const alignedTop = keepInRange(value);
|
||||
|
||||
if (componentRef.current) {
|
||||
componentRef.current.scrollTop = alignedTop;
|
||||
state.scrollTop = alignedTop;
|
||||
}
|
||||
|
||||
// ================================ Legacy ================================
|
||||
// Put ref here since the range is generate by follow
|
||||
const rangeRef = ref({ start: 0, end: state.mergedData.length });
|
||||
|
||||
// const diffItemRef = ref();
|
||||
// const [diffItem] = useDiffItem(mergedData, getKey);
|
||||
// diffItemRef.current = diffItem;
|
||||
state.scrollTop = alignedTop;
|
||||
}
|
||||
|
||||
// ================================ Height ================================
|
||||
const [setInstance, collectHeight, heights] = useHeights(getKey, null, null);
|
||||
|
@ -130,7 +124,6 @@ const List = {
|
|||
const currentItemBottom =
|
||||
itemTop + (cacheHeight === undefined ? props.itemHeight : cacheHeight);
|
||||
|
||||
// Check item top in the range
|
||||
if (currentItemBottom >= state.scrollTop && startIndex === undefined) {
|
||||
startIndex = i;
|
||||
startOffset = itemTop;
|
||||
|
@ -156,8 +149,6 @@ const List = {
|
|||
|
||||
// Give cache to improve scroll experience
|
||||
endIndex = Math.min(endIndex + 1, state.mergedData.length);
|
||||
rangeRef.value.start = startIndex;
|
||||
rangeRef.value.end = endIndex;
|
||||
return {
|
||||
scrollHeight: itemTop,
|
||||
start: startIndex,
|
||||
|
@ -166,7 +157,7 @@ const List = {
|
|||
};
|
||||
});
|
||||
// =============================== In Range ===============================
|
||||
const maxScrollHeight = computed(() => calRes.scrollHeight - props.height);
|
||||
const maxScrollHeight = computed(() => calRes.value.scrollHeight - props.height);
|
||||
|
||||
function keepInRange(newScrollTop) {
|
||||
let newTop = Math.max(newScrollTop, 0);
|
||||
|
@ -223,29 +214,29 @@ const List = {
|
|||
});
|
||||
watchEffect(() => {
|
||||
nextTick(() => {
|
||||
componentRef.current.removeEventListener('wheel', onRawWheel);
|
||||
componentRef.current.removeEventListener('DOMMouseScroll', onFireFoxScroll);
|
||||
componentRef.current.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
|
||||
|
||||
if (componentRef.current) {
|
||||
// Firefox only
|
||||
function onMozMousePixelScroll(e) {
|
||||
if (inVirtual.value) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
componentRef.current.removeEventListener('wheel', onRawWheel);
|
||||
componentRef.current.removeEventListener('DOMMouseScroll', onFireFoxScroll);
|
||||
componentRef.current.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
|
||||
componentRef.current.addEventListener('wheel', onRawWheel);
|
||||
componentRef.current.addEventListener('DOMMouseScroll', onFireFoxScroll);
|
||||
componentRef.current.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ================================= Ref ==================================
|
||||
const scrollTo = useScrollTo(
|
||||
componentRef,
|
||||
state.mergedData,
|
||||
state,
|
||||
heights,
|
||||
props.itemHeight,
|
||||
props,
|
||||
getKey,
|
||||
collectHeight,
|
||||
syncScrollTop,
|
||||
|
@ -288,7 +279,7 @@ const List = {
|
|||
height,
|
||||
itemHeight,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
fullHeight = true,
|
||||
fullHeight,
|
||||
data,
|
||||
itemKey,
|
||||
virtual,
|
||||
|
|
|
@ -76,8 +76,10 @@ export default {
|
|||
delayHidden() {
|
||||
clearTimeout(this.visibleTimeout);
|
||||
this.state.visible = true;
|
||||
|
||||
this.visibleTimeout = setTimeout(() => {
|
||||
this.state.visible = false;
|
||||
this.$forceUpdate(); // why ?
|
||||
}, 2000);
|
||||
},
|
||||
|
||||
|
@ -191,7 +193,6 @@ export default {
|
|||
const { prefixCls } = this.$props;
|
||||
const spinHeight = this.getSpinHeight() + 'px';
|
||||
const top = this.getTop() + 'px';
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={this.scrollbarRef}
|
||||
|
@ -202,7 +203,7 @@ export default {
|
|||
bottom: 0,
|
||||
right: 0,
|
||||
position: 'absolute',
|
||||
// display: visible ? null : 'none',
|
||||
display: visible ? null : 'none',
|
||||
}}
|
||||
onMousedown={this.onContainerMouseDown}
|
||||
onMousemove={this.delayHidden}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
import { ref, toRaw, watch } from 'vue';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import { findListDiffIndex } from '../utils/algorithmUtil';
|
||||
|
||||
export default function useDiffItem(data, getKey, onDiff) {
|
||||
const diffItem = ref(null);
|
||||
let prevData = cloneDeep(toRaw(data));
|
||||
watch(data, val => {
|
||||
const diff = findListDiffIndex(prevData || [], val || [], getKey);
|
||||
if (diff?.index !== undefined) {
|
||||
onDiff?.(diff.index);
|
||||
diffItem = val[diff.index];
|
||||
}
|
||||
prevData = cloneDeep(toRaw(val));
|
||||
});
|
||||
|
||||
return [diffItem];
|
||||
}
|
|
@ -61,14 +61,11 @@ export default function useMobileTouchMove(inVirtual, listRef, callback) {
|
|||
}
|
||||
};
|
||||
watch(inVirtual, val => {
|
||||
if (val.value) {
|
||||
listRef.current.addEventListener('touchstart', onTouchStart);
|
||||
}
|
||||
|
||||
return () => {
|
||||
listRef.current.removeEventListener('touchstart', onTouchStart);
|
||||
cleanUpEvents();
|
||||
clearInterval(interval);
|
||||
};
|
||||
if (val.value) {
|
||||
listRef.current.addEventListener('touchstart', onTouchStart);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { reactive } from 'vue';
|
||||
|
||||
export default (isScrollAtTop, isScrollAtBottom) => {
|
||||
// Do lock for a wheel when scrolling
|
||||
let lock = false;
|
||||
|
@ -13,21 +11,12 @@ export default (isScrollAtTop, isScrollAtBottom) => {
|
|||
lock = false;
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// Pass to ref since global add is in closure
|
||||
const scrollPingRef = reactive({
|
||||
top: isScrollAtTop.value,
|
||||
bottom: isScrollAtBottom.value,
|
||||
});
|
||||
// scrollPingRef.value.top = isScrollAtTop;
|
||||
// scrollPingRef.value.bottom = isScrollAtBottom;
|
||||
|
||||
return (deltaY, smoothOffset = false) => {
|
||||
const originScroll =
|
||||
// Pass origin wheel when on the top
|
||||
(deltaY < 0 && scrollPingRef.top) ||
|
||||
(deltaY < 0 && isScrollAtTop.value) ||
|
||||
// Pass origin wheel when on the bottom
|
||||
(deltaY > 0 && scrollPingRef.bottom);
|
||||
(deltaY > 0 && isScrollAtBottom.value);
|
||||
|
||||
if (smoothOffset && originScroll) {
|
||||
// No need lock anymore when it's smooth offset from touchMove interval
|
||||
|
|
|
@ -4,9 +4,9 @@ import raf from '../../_util/raf';
|
|||
|
||||
export default function useScrollTo(
|
||||
containerRef,
|
||||
data,
|
||||
state,
|
||||
heights,
|
||||
itemHeight,
|
||||
props,
|
||||
getKey,
|
||||
collectHeight,
|
||||
syncScrollTop,
|
||||
|
@ -15,7 +15,8 @@ export default function useScrollTo(
|
|||
|
||||
return arg => {
|
||||
raf.cancel(scroll);
|
||||
|
||||
const data = state.mergedData;
|
||||
const itemHeight = props.itemHeight;
|
||||
if (typeof arg === 'number') {
|
||||
syncScrollTop(arg);
|
||||
} else if (arg && typeof arg === 'object') {
|
||||
|
|
Loading…
Reference in New Issue