fix: requestAnimationFrame error in ssr, close #4833
parent
7b03f8a739
commit
a938bcb4de
|
@ -1,5 +1,6 @@
|
|||
import cssAnimation from './css-animation';
|
||||
import { nextTick } from 'vue';
|
||||
import { requestAnimationTimeout, cancelAnimationTimeout } from './requestAnimationTimeout';
|
||||
|
||||
function animate(node, show, done) {
|
||||
let height;
|
||||
|
@ -8,7 +9,7 @@ function animate(node, show, done) {
|
|||
return cssAnimation(node, 'ant-motion-collapse-legacy', {
|
||||
start() {
|
||||
if (appearRequestAnimationFrameId) {
|
||||
cancelAnimationFrame(appearRequestAnimationFrameId);
|
||||
cancelAnimationTimeout(appearRequestAnimationFrameId);
|
||||
}
|
||||
if (!show) {
|
||||
node.style.height = `${node.offsetHeight}px`;
|
||||
|
@ -18,7 +19,7 @@ function animate(node, show, done) {
|
|||
// not get offsetHeight when appear
|
||||
// set it into raf get correct offsetHeight
|
||||
if (height === 0) {
|
||||
appearRequestAnimationFrameId = requestAnimationFrame(() => {
|
||||
appearRequestAnimationFrameId = requestAnimationTimeout(() => {
|
||||
height = node.offsetHeight;
|
||||
node.style.height = '0px';
|
||||
node.style.opacity = '0';
|
||||
|
@ -31,19 +32,19 @@ function animate(node, show, done) {
|
|||
},
|
||||
active() {
|
||||
if (requestAnimationFrameId) {
|
||||
cancelAnimationFrame(requestAnimationFrameId);
|
||||
cancelAnimationTimeout(requestAnimationFrameId);
|
||||
}
|
||||
requestAnimationFrameId = requestAnimationFrame(() => {
|
||||
requestAnimationFrameId = requestAnimationTimeout(() => {
|
||||
node.style.height = `${show ? height : 0}px`;
|
||||
node.style.opacity = show ? '1' : '0';
|
||||
});
|
||||
},
|
||||
end() {
|
||||
if (appearRequestAnimationFrameId) {
|
||||
cancelAnimationFrame(appearRequestAnimationFrameId);
|
||||
cancelAnimationTimeout(appearRequestAnimationFrameId);
|
||||
}
|
||||
if (requestAnimationFrameId) {
|
||||
cancelAnimationFrame(requestAnimationFrameId);
|
||||
cancelAnimationTimeout(requestAnimationFrameId);
|
||||
}
|
||||
node.style.height = '';
|
||||
node.style.opacity = '';
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
interface RafMap {
|
||||
[id: number]: number;
|
||||
}
|
||||
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from './getRequestAnimationFrame';
|
||||
|
||||
let id = 0;
|
||||
const ids: RafMap = {};
|
||||
const oriRaf = getRequestAnimationFrame();
|
||||
|
||||
export type RafFrame = {
|
||||
id: number;
|
||||
};
|
||||
// Support call raf with delay specified frame
|
||||
export default function raf(callback: () => void, delayFrames = 1): number {
|
||||
const myId: number = id++;
|
||||
export default function raf(callback: () => void, delayFrames = 1): { id: number } {
|
||||
let restFrames: number = delayFrames;
|
||||
|
||||
function internalCallback() {
|
||||
|
@ -15,22 +14,20 @@ export default function raf(callback: () => void, delayFrames = 1): number {
|
|||
|
||||
if (restFrames <= 0) {
|
||||
callback();
|
||||
delete ids[myId];
|
||||
} else {
|
||||
ids[myId] = requestAnimationFrame(internalCallback);
|
||||
frame.id = oriRaf(internalCallback);
|
||||
}
|
||||
}
|
||||
|
||||
ids[myId] = requestAnimationFrame(internalCallback);
|
||||
const frame = {
|
||||
id: oriRaf(internalCallback),
|
||||
};
|
||||
|
||||
return myId;
|
||||
return frame;
|
||||
}
|
||||
|
||||
raf.cancel = function cancel(pid?: number) {
|
||||
if (pid === undefined) return;
|
||||
raf.cancel = function cancel(frame?: { id: number }) {
|
||||
if (!frame) return;
|
||||
|
||||
cancelAnimationFrame(ids[pid]);
|
||||
delete ids[pid];
|
||||
cancelRequestAnimationFrame(frame.id);
|
||||
};
|
||||
|
||||
raf.ids = ids; // export this for test usage
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import type { RafFrame } from './raf';
|
||||
import raf from './raf';
|
||||
|
||||
export default function throttleByAnimationFrame(fn: (...args: any[]) => void) {
|
||||
let requestId: number | null;
|
||||
let requestId: RafFrame;
|
||||
|
||||
const later = (args: any[]) => () => {
|
||||
requestId = null;
|
||||
|
@ -8,11 +11,11 @@ export default function throttleByAnimationFrame(fn: (...args: any[]) => void) {
|
|||
|
||||
const throttled = (...args: any[]) => {
|
||||
if (requestId == null) {
|
||||
requestId = requestAnimationFrame(later(args));
|
||||
requestId = raf(later(args));
|
||||
}
|
||||
};
|
||||
|
||||
(throttled as any).cancel = () => cancelAnimationFrame(requestId!);
|
||||
(throttled as any).cancel = () => raf.cancel(requestId!);
|
||||
|
||||
return throttled;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { computed, defineComponent, onBeforeUnmount, ref, watch } from 'vue';
|
|||
import type { MenuMode } from './interface';
|
||||
import { useInjectMenu } from './hooks/useMenuContext';
|
||||
import { placements, placementsRtl } from './placements';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import classNames from '../../_util/classNames';
|
||||
|
||||
|
@ -48,7 +49,7 @@ export default defineComponent({
|
|||
|
||||
const popupPlacement = computed(() => popupPlacementMap[props.mode]);
|
||||
|
||||
const visibleRef = ref<number>();
|
||||
const visibleRef = ref<RafFrame>();
|
||||
watch(
|
||||
() => props.visible,
|
||||
visible => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { onBeforeUnmount, watch, onActivated, defineComponent, ref } from 'vue';
|
||||
import Tooltip, { tooltipProps } from '../tooltip';
|
||||
import type { RafFrame } from '../_util/raf';
|
||||
import raf from '../_util/raf';
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -9,7 +10,7 @@ export default defineComponent({
|
|||
setup(props, { attrs, slots }) {
|
||||
const innerRef = ref<any>(null);
|
||||
|
||||
const rafRef = ref<number | null>(null);
|
||||
const rafRef = ref<RafFrame>(null);
|
||||
|
||||
function cancelKeepAlign() {
|
||||
raf.cancel(rafRef.value!);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import type { RafFrame } from '../../../_util/raf';
|
||||
import raf from '../../../_util/raf';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
|
||||
|
@ -5,7 +6,7 @@ type SetActionType<T> = Partial<T> | ((state: T) => Partial<T>);
|
|||
export default function useFrameSetState<T extends object>(
|
||||
initial: T,
|
||||
): [Record<string, any>, (newState: SetActionType<T>) => void] {
|
||||
const frame = ref(null);
|
||||
const frame = ref<RafFrame>(null);
|
||||
const state = reactive({ ...initial });
|
||||
const queue = ref<SetActionType<T>[]>([]);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import type { ComputedRef, Ref, UnwrapRef } from 'vue';
|
||||
import { ref, onBeforeUnmount, watch } from 'vue';
|
||||
import type { ValueTextConfig } from './useValueTexts';
|
||||
|
@ -8,15 +10,15 @@ export default function useHoverValue<DateType>(
|
|||
{ formatList, generateConfig, locale }: ValueTextConfig<DateType>,
|
||||
): [ComputedRef<string>, (date: DateType) => void, (immediately?: boolean) => void] {
|
||||
const innerValue = ref<DateType>(null);
|
||||
const raf = ref(null);
|
||||
let rafId: RafFrame;
|
||||
|
||||
function setValue(val: DateType, immediately = false) {
|
||||
cancelAnimationFrame(raf.value);
|
||||
raf.cancel(rafId);
|
||||
if (immediately) {
|
||||
innerValue.value = val as UnwrapRef<DateType>;
|
||||
return;
|
||||
}
|
||||
raf.value = requestAnimationFrame(() => {
|
||||
rafId = raf(() => {
|
||||
innerValue.value = val as UnwrapRef<DateType>;
|
||||
});
|
||||
}
|
||||
|
@ -38,7 +40,7 @@ export default function useHoverValue<DateType>(
|
|||
onLeave(true);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
cancelAnimationFrame(raf.value);
|
||||
raf.cancel(rafId);
|
||||
});
|
||||
|
||||
return [firstText, onEnter, onLeave];
|
||||
|
|
|
@ -3,6 +3,7 @@ import { onBeforeUnmount, watchEffect, watch, ref, computed } from 'vue';
|
|||
import type { FocusEventHandler } from '../../_util/EventInterface';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
import { addGlobalMousedownEvent, getTargetFromEvent } from '../utils/uiUtil';
|
||||
import raf from '../../_util/raf';
|
||||
|
||||
export default function usePickerInput({
|
||||
open,
|
||||
|
@ -161,7 +162,7 @@ export default function usePickerInput({
|
|||
preventBlurRef.value = true;
|
||||
|
||||
// Always set back in case `onBlur` prevented by user
|
||||
requestAnimationFrame(() => {
|
||||
raf(() => {
|
||||
preventBlurRef.value = false;
|
||||
});
|
||||
} else if (!focused.value || clickedOutside) {
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import isVisible from '../../vc-util/Dom/isVisible';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import type { GenerateConfig } from '../generate';
|
||||
import type { CustomFormat, PanelMode, PickerMode } from '../interface';
|
||||
|
||||
const scrollIds = new Map<HTMLElement, number>();
|
||||
const scrollIds = new Map<HTMLElement, RafFrame>();
|
||||
|
||||
/** Trigger when element is visible in view */
|
||||
export function waitElementReady(element: HTMLElement, callback: () => void): () => void {
|
||||
let id: number;
|
||||
let id: RafFrame;
|
||||
|
||||
function tryOrNextFrame() {
|
||||
if (isVisible(element)) {
|
||||
|
@ -30,14 +31,14 @@ export function waitElementReady(element: HTMLElement, callback: () => void): ()
|
|||
/* eslint-disable no-param-reassign */
|
||||
export function scrollTo(element: HTMLElement, to: number, duration: number) {
|
||||
if (scrollIds.get(element)) {
|
||||
cancelAnimationFrame(scrollIds.get(element)!);
|
||||
raf.cancel(scrollIds.get(element)!);
|
||||
}
|
||||
|
||||
// jump to target if duration zero
|
||||
if (duration <= 0) {
|
||||
scrollIds.set(
|
||||
element,
|
||||
requestAnimationFrame(() => {
|
||||
raf(() => {
|
||||
element.scrollTop = to;
|
||||
}),
|
||||
);
|
||||
|
@ -49,7 +50,7 @@ export function scrollTo(element: HTMLElement, to: number, duration: number) {
|
|||
|
||||
scrollIds.set(
|
||||
element,
|
||||
requestAnimationFrame(() => {
|
||||
raf(() => {
|
||||
element.scrollTop += perTick;
|
||||
if (element.scrollTop !== to) {
|
||||
scrollTo(element, to, duration - 10);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import addEventListenerWrap from '../../vc-util/Dom/addEventListener';
|
||||
import type { EventHandler } from '../../_util/EventInterface';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import { defineComponent, onUnmounted, computed, ref, watchEffect, getCurrentInstance } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
|
@ -73,7 +74,7 @@ export default defineComponent({
|
|||
const instance = getCurrentInstance();
|
||||
let baseWidth = 0;
|
||||
const dragging = ref(false);
|
||||
let rafId: number;
|
||||
let rafId: RafFrame;
|
||||
const updateWidth = (e: HandleEvent) => {
|
||||
let pageX = 0;
|
||||
if (e.touches) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import type { Ref, UnwrapRef } from 'vue';
|
||||
import { onBeforeUnmount, ref, shallowRef } from 'vue';
|
||||
|
@ -8,7 +9,7 @@ export function useLayoutState<State>(
|
|||
defaultState: State,
|
||||
): [Ref<State>, (updater: Updater<State>) => void] {
|
||||
const stateRef = shallowRef<State>(defaultState);
|
||||
let rafId: number;
|
||||
let rafId: RafFrame;
|
||||
const updateBatchRef = shallowRef<Updater<State>[]>([]);
|
||||
function setFrameState(updater: Updater<State>) {
|
||||
updateBatchRef.value.push(updater);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type { Ref } from 'vue';
|
||||
import { nextTick, onBeforeUnmount, ref, watch, onMounted } from 'vue';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
|
||||
/**
|
||||
|
@ -23,7 +24,7 @@ export default (
|
|||
doMeasure: Func,
|
||||
): [Ref<PopupStatus>, (callback?: () => void) => void] => {
|
||||
const status = ref<PopupStatus>(null);
|
||||
const rafRef = ref<number>();
|
||||
const rafRef = ref<RafFrame>();
|
||||
const destroyRef = ref(false);
|
||||
function setStatus(nextStatus: PopupStatus) {
|
||||
if (!destroyRef.value) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { Ref } from 'vue';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import isFF from '../utils/isFirefox';
|
||||
import useOriginScroll from './useOriginScroll';
|
||||
|
@ -15,7 +16,7 @@ export default function useFrameWheel(
|
|||
onWheelDelta: (offset: number) => void,
|
||||
): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void] {
|
||||
let offsetRef = 0;
|
||||
let nextFrame: number | null | undefined = null;
|
||||
let nextFrame: RafFrame = null;
|
||||
|
||||
// Firefox patch
|
||||
let wheelValue = null;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type { Data } from '../../_util/type';
|
||||
import type { ComputedRef, Ref } from 'vue';
|
||||
import type { RafFrame } from '../../_util/raf';
|
||||
import raf from '../../_util/raf';
|
||||
import type { GetKey } from '../interface';
|
||||
|
||||
|
@ -13,7 +14,7 @@ export default function useScrollTo(
|
|||
syncScrollTop: (newTop: number) => void,
|
||||
triggerFlash: () => void,
|
||||
) {
|
||||
let scroll: number | null = null;
|
||||
let scroll: RafFrame = null;
|
||||
|
||||
return (arg?: any) => {
|
||||
// When not argument provided, we think dev may want to show the scrollbar
|
||||
|
|
|
@ -102,7 +102,6 @@
|
|||
"@types/markdown-it": "^10.0.2",
|
||||
"@types/node": "^14.0.0",
|
||||
"@types/postcss-load-config": "^2.0.1",
|
||||
"@types/raf": "^3.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.1.0",
|
||||
"@typescript-eslint/parser": "^4.1.0",
|
||||
"@vitejs/plugin-vue": "^1.2.4",
|
||||
|
|
Loading…
Reference in New Issue