我正在尝试制作一个带有以下方法的React幻灯片组件:
- 组件通过props接收一个幻灯片数组(React组件),一次显示一个幻灯片,从幻灯片编号1开始(索引0)。 - 当前显示的幻灯片(也称为“当前幻灯片”)会显示出来,而其他幻灯片则不会显示。 - 在导航时(开始幻灯片动画),目标幻灯片将被添加到包装器中。如果目标幻灯片在当前幻灯片之前(即目标幻灯片在幻灯片数组中具有较小的索引,即点击下一个),它将以从左侧滑入的动画效果添加,动画效果为`left`从`-100%`到`0`(从左侧滑入);如果目标幻灯片在当前幻灯片之后(即目标幻灯片具有较大的索引,即点击上一个),它将以从右侧滑入的动画效果添加,动画效果为`from 100% to 0`(从右侧滑入);对于当前幻灯片,将相应地添加一个动画类`left 0 to 100%`或`left 0 to -100%`(向右或向左滑出)。 - 当动画结束时,当前幻灯片将更改为滑入的幻灯片(目标幻灯片),并且以前的当前幻灯片将被移除。
我注意到,如果我将目标幻灯片放在包装组件中的当前幻灯片之后,就不会有任何问题,但如果我将其放在之前,它会闪烁。
我想了解为什么会这样?
不闪烁(动画幻灯片在当前幻灯片之后): 演示:https://stackblitz.com/edit/vitejs-vite-wnedwd?file=src%2FSlides.jsx 闪烁(动画幻灯片在当前幻灯片之前): 演示:https://stackblitz.com/edit/vitejs-vite-hy6rsp?file=src%2FSlides.jsx
- 组件通过props接收一个幻灯片数组(React组件),一次显示一个幻灯片,从幻灯片编号1开始(索引0)。 - 当前显示的幻灯片(也称为“当前幻灯片”)会显示出来,而其他幻灯片则不会显示。 - 在导航时(开始幻灯片动画),目标幻灯片将被添加到包装器中。如果目标幻灯片在当前幻灯片之前(即目标幻灯片在幻灯片数组中具有较小的索引,即点击下一个),它将以从左侧滑入的动画效果添加,动画效果为`left`从`-100%`到`0`(从左侧滑入);如果目标幻灯片在当前幻灯片之后(即目标幻灯片具有较大的索引,即点击上一个),它将以从右侧滑入的动画效果添加,动画效果为`from 100% to 0`(从右侧滑入);对于当前幻灯片,将相应地添加一个动画类`left 0 to 100%`或`left 0 to -100%`(向右或向左滑出)。 - 当动画结束时,当前幻灯片将更改为滑入的幻灯片(目标幻灯片),并且以前的当前幻灯片将被移除。
Slides component (glitching):
import React, { useCallback, useState } from 'react';
import styles from './Slides.module.css';
function Slides({ slides, onBrowse, onBrowseEnd, className, ...rest }) {
const [currentSlide, setCurrentSlide] = useState(1); //slide number
const [animSlide, setAnimSlide] = useState(null); //destination slide number
const browse = useCallback((slide) => {
if (slide <= slides.length) {
setAnimSlide(slide);
console.log(slide);
}
onBrowse && onBrowse(slide);
});
console.log('rerender');
const animationEndCallback = useCallback(() => {
setCurrentSlide(animSlide);
setAnimSlide(null);
}, [animSlide]);
return (
<div className={styles.wrapper + ' ' + className} {...rest}>
<div className={styles.slides}>
{animSlide &&
React.cloneElement(slides[animSlide - 1], {
className: `
${styles.absolute}
${styles.slide}
${slides[animSlide - 1]?.props?.className}
${
animSlide < currentSlide
? styles.slide_in_from_left
: styles.slide_in_from_right
}
`,
})}
{React.cloneElement(slides[currentSlide - 1], {
className: `
${styles.absolute}
${styles.slide}
${slides[currentSlide - 1]?.props?.className}
${
animSlide &&
(animSlide < currentSlide
? styles.slide_right
: styles.slide_left)
}
`,
onAnimationEnd: animationEndCallback,
})}
</div>
{
}
<div className={styles.navcon}>
<button
onClick={() => {
browse(currentSlide - 1);
}}
disabled={!(currentSlide > 1)}
>
Previuos
</button>
<button
onClick={() => {
browse(currentSlide + 1);
}}
disabled={
!(animSlide
? animSlide < slides.length
: currentSlide < slides.length)
}
>
Next
</button>
</div>
</div>
);
}
export default Slides;
我想了解为什么会这样?
不闪烁(动画幻灯片在当前幻灯片之后): 演示:https://stackblitz.com/edit/vitejs-vite-wnedwd?file=src%2FSlides.jsx 闪烁(动画幻灯片在当前幻灯片之前): 演示:https://stackblitz.com/edit/vitejs-vite-hy6rsp?file=src%2FSlides.jsx
z-index
,后一个组件将自动位于前一个组件之上。试一试 - Hadi KARz-index
,后一个组件将自动位于前一个组件之上。试一试 - Hadi KAR