Вопрос или проблема
Я пытался анимировать свои элементы span с помощью селектора “.dots”, но получил предупреждение:
Эти span представляют количество видео на контрольной панели.
Цель GSAP .dots не найдена. https://gsap.com
для обеих позиций
Исходный код:
const setupTimelines = () => {
gsap.set(".dots", {
visibility: "hidden",
opacity: 0,
});
gsap.to(".dots", {
visibility: "visible",
stagger: 0.1,
opacity: 1,
});
}
useGSAP(setupTimelines);
<div className="content">
{videos.map((_, i) => (
<span className="dots" key={i}>
<span className="progress" />
</span>
))}
</div>
Изменения, которые я пытался внести с помощью useGSAP и useEffect, но это не сработало:
useGSAP(() => {
if (videos.length > 0) {
setupTimelines();
}
},[videos]);
Возможно, это связано с тем, что он не находит .dots
, даже если видео загружены. Вы можете попробовать проверить, действительно ли .dots
находятся в DOM.
useEffect(() => {
if (videos.length > 0) {
const dots = document.querySelectorAll('.dots');
if (dots.length > 0) {
setupTimelines();
}
}
}, [videos]);
Ответ или решение
Конечно! Проблема, с которой вы столкнулись ("GSAP target .dots not found"), возникает из-за того, что анимация запускается до того, как элементы с классом .dots
фактически отрисовываются в DOM. Давайте разберемся, как это исправить.
Решение
В вашем случае вы хотите гарантировать, что анимация запускается только после того, как videos
загружены и элементы .dots
есть в DOM. Мы можем использовать useEffect
, чтобы следить за изменением videos
, и запускать анимацию только тогда, когда элементы .dots
существуют.
Вот доработанный код:
import React, { useEffect } from 'react';
import { gsap } from 'gsap';
const setupTimelines = () => {
gsap.set(".dots", {
visibility: "hidden",
opacity: 0,
});
gsap.to(".dots", {
visibility: "visible",
stagger: 0.1,
opacity: 1,
});
};
const VideoComponent = ({ videos }) => {
useEffect(() => {
if (videos.length > 0) {
const dots = document.querySelectorAll('.dots');
if (dots.length > 0) {
setupTimelines();
}
}
}, [videos]);
return (
<div className="content">
{videos.map((_, i) => (
<span className="dots" key={i}>
<span className="progress" />
</span>
))}
</div>
);
};
export default VideoComponent;
Объяснение изменений:
-
Проверка наличия элементов в DOM: Мы используем
document.querySelectorAll('.dots')
, чтобы убедиться, что хотя бы один элемент с классом.dots
существует перед запуском анимации. Это предотвращает ошибку "target not found". -
Использование
useEffect
: Мы следим за изменениями массиваvideos
. С запуском эффекта мы проверяем, есть ли элементы.dots
, и, если да, вызываемsetupTimelines()
для инициализации анимации. -
Скрытие и показ: Вы устанавливаете
visibility: "hidden"
в первом вызовеgsap.set
, что позволяет избежать визуального ожидания до завершения анимации.
Теперь ваша анимация будет успешно запускаться каждый раз, когда новое видео добавляется в массив videos
, и элементы .dots
будут присутствовать в DOM.