ant-design-vue/components/vc-virtual-list/hooks/useFrameWheel.ts

62 lines
1.6 KiB
TypeScript
Raw Normal View History

2020-10-01 09:20:10 +00:00
import { Ref } from 'vue';
2020-09-28 11:14:00 +00:00
import raf from '../../_util/raf';
import isFF from '../utils/isFirefox';
import useOriginScroll from './useOriginScroll';
2020-10-01 09:20:10 +00:00
interface FireFoxDOMMouseScrollEvent {
detail: number;
preventDefault: Function;
}
export default function useFrameWheel(
inVirtual: Ref<boolean>,
isScrollAtTop: Ref<boolean>,
isScrollAtBottom: Ref<boolean>,
onWheelDelta: (offset: number) => void,
): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void] {
2020-09-28 11:14:00 +00:00
let offsetRef = 0;
2020-10-01 09:20:10 +00:00
let nextFrame: number | null | undefined = null;
2020-09-28 11:14:00 +00:00
// Firefox patch
2020-10-02 14:28:41 +00:00
let wheelValue = null;
2020-09-28 11:14:00 +00:00
let isMouseScroll = false;
// Scroll status sync
const originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom);
2020-10-01 09:20:10 +00:00
function onWheel(event: { preventDefault?: any; deltaY?: any }) {
2020-09-28 11:14:00 +00:00
if (!inVirtual.value) return;
2020-10-01 09:20:10 +00:00
raf.cancel(nextFrame!);
2020-09-28 11:14:00 +00:00
const { deltaY } = event;
offsetRef += deltaY;
wheelValue = deltaY;
// Do nothing when scroll at the edge, Skip check when is in scroll
if (originScroll(deltaY)) return;
// Proxy of scroll events
if (!isFF) {
event.preventDefault();
}
nextFrame = raf(() => {
// Patch a multiple for Firefox to fix wheel number too small
// ref: https://github.com/ant-design/ant-design/issues/26372#issuecomment-679460266
const patchMultiple = isMouseScroll ? 10 : 1;
onWheelDelta(offsetRef * patchMultiple);
offsetRef = 0;
});
}
// A patch for firefox
2020-10-01 09:20:10 +00:00
function onFireFoxScroll(event: { detail: any }) {
2020-09-28 11:14:00 +00:00
if (!inVirtual.value) return;
isMouseScroll = event.detail === wheelValue;
}
return [onWheel, onFireFoxScroll];
}