首页 文章

使用带反应路由器的锚点

提问于
浏览
24

如何使用react-router,并将链接导航到特定页面上的特定位置? (例如 /home-page#section-three

Details

我在我的React应用程序中使用 react-router .

我有一个站点范围的导航栏,需要链接到页面的特定部分,如 /home-page#section-three .

因此,即使您说 /blog ,单击此链接仍将加载主页,第三部分滚动到视图中 . 这正是标准 <a href="/home-page#section-three> 的工作方式 .

Note :react-router的创建者没有给出明确的答案 . 他们说它正在进行中,同时使用其他人's answers. I'll尽我所能保持这个问题的最新进展和可能的解决方案,直到出现主导的问题 .

Research


How to use normal anchor links with react-router

这个问题是从2015年(所以10年前的反应时间) . 最热烈的回答是使用 HistoryLocation 而不是 HashLocation . 基本上这意味着将位置存储在窗口历史记录中,而不是存储在哈希片段中 .

坏消息是......即使使用HistoryLocation(大多数教程和文档在2016年所说的内容),锚标签仍然不起作用 .


https://github.com/ReactTraining/react-router/issues/394

ReactTraining上的一个线程,关于如何使用anchor链接与react-router . 这是没有确认的答案 . 请注意,因为大多数建议的答案都已过时(例如在 <Link> 中使用"hash"道具)


5 回答

  • 18

    这是我找到的一个解决方案(2016年10月) . 它是跨浏览器兼容的(在ie,ff,chrome,mobile safari,safari中测试) .

    您可以为路由器提供 onUpdate 属性 . 只要路由更新,就会调用此方法 . 此解决方案使用onUpdate属性检查是否存在与哈希匹配的DOM元素,然后在路由转换完成后滚动到该元素 .

    您必须使用browserHistory而不是hashHistory .

    答案是"Rafrax"在thread中 .

    Add this code to the place where you define <Router>:

    import React from 'react';
    import { render } from 'react-dom';
    import { Router, Route, browserHistory } from 'react-router';
    
    const routes = (
      // your routes
    );
    
    function hashLinkScroll() {
      const { hash } = window.location;
      if (hash !== '') {
        // Push onto callback queue so it runs after the DOM is updated,
        // this is required when navigating from a different page so that
        // the element is rendered on the page before trying to getElementById.
        setTimeout(() => {
          const id = hash.replace('#', '');
          const element = document.getElementById(id);
          if (element) element.scrollIntoView();
        }, 0);
      }
    }
    
    render(
      <Router
        history={browserHistory}
        routes={routes}
        onUpdate={hashLinkScroll}
      />,
      document.getElementById('root')
    )
    

    如果您感觉懒惰并且不想复制该代码,则可以使用仅为您定义该功能的Anchorate . https://github.com/adjohnson916/anchorate

  • 1

    React Router Hash Link为我工作 . 易于安装和实施:

    $ npm install --save react-router-hash-link
    

    在component.js中将其导入为Link:

    import { HashLink as Link } from 'react-router-hash-link';
    

    而不是使用锚 <a> ,使用 <Link>

    <Link to="home-page#section-three>Section three</Link>
    

    注意:我使用 HashRouter 而不是 Router

  • 13

    只是避免使用react-router进行本地滚动:

    document.getElementById('myElementSomewhere').scrollIntoView()
    
  • 1

    另一种选择:react-scrollchor https://www.npmjs.com/package/react-scrollchor

    react-scrollchor:一个React组件,用于滚动到具有平滑动画的#hash链接 . Scrollchor是Scroll和Anchor的混合体

    注意:它不使用react-router

  • 1

    https://stackoverflow.com/a/40280486/515585的问题有时候,如果该部分依赖于某些异步操作,则仍会呈现或加载具有id的元素 . 以下函数将尝试按id查找元素并导航到它并每100ms重试一次,直到最多重试50次:

    scrollToLocation = () => {
      const { hash } = window.location;
      if (hash !== '') {
        let retries = 0;
        const id = hash.replace('#', '');
        const scroll = () => {
          retries += 0;
          if (retries > 50) return;
          const element = document.getElementById(id);
          if (element) {
            setTimeout(() => element.scrollIntoView(), 0);
          } else {
            setTimeout(scroll, 100);
          }
        };
        scroll();
      }
    }
    

相关问题