首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >恢复滚动y位置react-router-dom

恢复滚动y位置react-router-dom
EN

Stack Overflow用户
提问于 2021-06-10 22:38:49
回答 2查看 202关注 0票数 1

Here我复制了一个简单的代码片段,其中包含使用react-spring进行的页面转换。

有没有办法在点击浏览器的后退按钮时恢复上一页的滚动位置?

周围有很多相关的QA,但我在使用动画库时找不到任何解决方案

你知道如何实现这一点吗?

EN

回答 2

Stack Overflow用户

发布于 2021-06-19 03:41:58

在导航时恢复scrollY位置并不容易。我们可能需要一个上下文来存储页面的y个位置。下面是我的解决方案。

用于侦听滚动事件的自定义挂钩(hooks/scroll.js)

代码语言:javascript
复制
import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';

export const useScrollPositions = () => {
  const [positions, setPositions] = useState(new Map());
  const location = useLocation();

  useEffect(() => {
    const listener = (ev) => {
      console.log('position: ', ev.target.scrollTop);
      positions.set(location.pathname, { 
        left: ev.target.scrollLeft, 
        top: ev.target.scrollTop
      });
      setPositions(new Map(positions));
    }

    window.addEventListener('scroll', listener, true);

    return () => {
      window.removeEventListener('scroll', listener, true);
    }
  }, [location]);

  return positions;
}

用于存储pages(context/scroll-context.js)的y位置的上下文

代码语言:javascript
复制
import { createContext } from 'react';

export const ScrollContext = createContext();

在上下文提供程序中包装所有页面的:App component

代码语言:javascript
复制
const App = () => {
  const location = useLocation();
  const positions = useScrollPositions();

  const transitions = useTransition(location, {
    from: { opacity: 0, transform: 'translate3d(100vw, 0, 0)' },
    enter: { opacity: 1, transform: 'translate3d(0, 0, 0)' },
    leave: { opacity: 0, transform: 'translate3d(-20vw, 0, 0)' },
  });

  return (
    <ScrollContext.Provider value={positions}>
      <GlobalStyles />
      <Switch>
        <Route path='/' exact component={Home} />
        <Route path="/about" component={About} />
      </Switch>
      {transitions((props, item) => (
        <animated.div style={props}>
          <Switch location={item}>
            <Route path="/" exact component={Home} />
            <Route path="/about" exact component={About} />
          </Switch>
        </animated.div>
      ))}
    </ScrollContext.Provider>
  );
};

执行滚动页面组件

代码语言:javascript
复制
import React, { useEffect, useRef, useContext } from 'react';
import { useLocation } from 'react-router-dom';
import { ScrollContext } from '../context/scroll-context';

const Page = ({children, ...rest}) => {

  const main = useRef();
  const positions = useContext(ScrollContext);
  const location = useLocation();

  useEffect(() => {
    if (main.current) {
      const position = positions.get(location.pathname);
      if (position && position.top) {
        main.current.scrollTop = position.top;
      }
    }
  }, [])

  return (
    <main {...rest} ref={main}>
      {children}
    </main>
  )
}

export default Page

注意::您必须包装此页面组件中的所有页面。这个页面组件(scroll: auto)的CSS样式也很重要。在现实的项目中,它可能需要更灵活的代码。无论如何,有关完整的工作项目,请查看here

票数 1
EN

Stack Overflow用户

发布于 2021-06-14 19:06:31

您可以在卸载组件时调用下面的方法,并将其保留。

代码语言:javascript
复制
export const getScrollPage = (): number => {
  let docScrollTop = 0;
  if (document.documentElement && document.documentElement !== null) {
    docScrollTop = document.documentElement.scrollTop;
  }
  return window.pageYOffset || docScrollTop;
};

使用scroll y位置的保留值并传递给下方函数。

代码语言:javascript
复制
export const scrollTo = (scrollnumber: number = 0): number =>
  window.requestAnimationFrame(() => {
    window.scrollTo(0, scrollnumber);
  });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67923424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档