Я создаю проект Next.js с Framer Motion для переходов страниц. Старая страница должна выскользнуть из текущей позиции прокрутки, а новая страница должна въехать, начиная с позиции прокрутки = 0.
Проблема:
После прокрутки домашней страницы вниз, когда я нажимаю ссылку перехода, новая страница ненадолго появляется в старой позиции прокрутки, прежде чем перейти наверх. Я хочу, чтобы он сразу начинался сверху, без видимого скачка.
Живое воспроизведение:
Минимальные фрагменты кода:
Код: Выделить всё
'use client';
import React, { ReactNode } from 'react';
import Link, { LinkProps } from 'next/link';
import { MouseEventHandler } from 'react';
import { useRouter } from 'next/navigation';
interface TransitionLinkProps extends LinkProps {
children: ReactNode;
className?: string;
}
export default function TransitionLink({ href, children, className }: TransitionLinkProps) {
const router = useRouter();
const handleClick: MouseEventHandler = (e) => {
e.preventDefault();
router.push(href.toString(), { scroll: false });
};
return (
{children}
);
}
Код: Выделить всё
'use client';
import React from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { usePathname } from 'next/navigation';
import { useContext, useRef, useEffect } from 'react';
import { LayoutRouterContext } from 'next/dist/shared/lib/app-router-context.shared-runtime';
function FrozenRouter(props: { children: React.ReactNode }) {
const context = useContext(LayoutRouterContext ?? {});
const frozen = useRef(context).current;
if (!frozen) return {props.children};
return (
{props.children}
);
}
export default function PageTransitionEffect({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
return (
{
// Only reset scroll when the *enter* animation finishes
window.scrollTo(0, 0);
}}
>
{children}
);
}
Код: Выделить всё
import type { Metadata } from 'next';
import '@/styles/reset.css';
import '@/app/globals.css';
import PageTransitionEffect from '@/components/PageTransitionEffect';
import Header from '@/components/Header';
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default function RootLayout({
children,
}: Readonly) {
return (
{children}
);
}
useLayoutEffect(() => window.scrollTo(0,0))
onAnimationStart при движении div
Заморозить/разморозить прокрутку по позиции: исправлено
прокрутка: false на router.push и Ссылка
Ожидаемое поведение:
Старая страница выскальзывает из текущей прокрутки, новая страница вставляется вверху без видимого перехода при прокрутке.
Вопрос:
Как заставить новую страницу немедленно начать переход при прокрутке = 0, не затрагивая старую страницу и не показывая переход?
Подробнее здесь: https://stackoverflow.com/questions/797 ... l-position
Мобильная версия