Остановите прокрутку Reach Router вниз по странице после перехода на новую страницу - PullRequest
0 голосов
/ 30 октября 2018

Когда я перехожу на новую страницу, Reach Router прокручивает содержимое страницы за заголовком (если содержимое достаточно длинное). Я предполагаю, что это для доступности, но это не обязательно для моего приложения, и это на самом деле довольно неприятно. Можно ли отключить это поведение?

Обратите внимание, что я говорю о Reach Router, а не React Router.

Reach Router

Ответы [ 4 ]

0 голосов
/ 11 июля 2019

Главный ответ здесь, хотя и решает проблему OP, вероятно, не является решением, которое нужно большинству людей, поскольку он отключает наиболее важную функцию доступности маршрутизатора Reach.

Тот факт, что маршрутизатор Reach фокусирует содержимое совпадающего <Route> на изменении маршрута, составляет по соображениям доступности - поэтому средства чтения с экрана и т. Д. Могут быть направлены на недавно обновленное релевантное содержимое при переходе к новая страница.

Для этого используется HTMLElement.focus() - см. Документы MDN здесь .

Проблема в том, что по умолчанию эта функция прокручивается до фокусируемого элемента. - это аргумент preventScroll, который можно использовать, чтобы отключить это поведение, но поддержка браузера его не очень хороша, и независимо от этого, Reach Router не использует его.

Подставка primary на Router используется, чтобы отключить это поведение для любых вложенных <Router>, которые у вас могут быть - это , а не , предназначенные для использования на вашем основной (основной) <Router> - отсюда и название.

Установка этого false на вашем основном <Router>, как подсказывает верхний ответ, «работает» в том смысле, что он останавливает поведение прокрутки , но это достигается простым отключением фокусировки. поведение полностью, что нарушает функцию доступности. Как я уже сказал, если вы сделаете это, вы нарушите одну из основных причин использования Reach Router.

Итак, в чем решение?

По сути, кажется, что этот побочный эффект HTMLElement.focus() - прокрутка к сфокусированному элементу - неизбежна. Поэтому, если вам нужна функция специальных возможностей, вы должны использовать прокрутку.

Но с учетом сказанного может быть обходной путь. Если вы будете прокручивать вручную верхнюю часть страницы, используя window.scrollTo(0, 0) при каждом изменении маршрута, я считаю, что это не «нарушит» функцию фокусировки с точки зрения доступности, но «исправит» поведение прокрутки с точки зрения UX.

Конечно, это немного хакерский и обязательный обходной путь, но я думаю, что это лучшее (возможно, единственное) решение этой проблемы без нарушения доступности.

Вот как я это реализовал

class OnRouteChangeWorker extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.location.pathname !== prevProps.location.pathname) {
      this.props.action()
    }
  }

  render() {
    return null
  }
}

const OnRouteChange = ({ action }) => (
  {/* 
      Location is an import from @reach/router, 
      provides current location from context 
  */}
  <Location>
    {({ location }) => <OnRouteChangeWorker location={location} action={action} />}
  </Location>
)

const Routes = () => (
  <>
    <Router>
      <LayoutWithHeaderBar path="/">
        <Home path="/" />
        <Foo path="/foo" />
        <Bar path="/bar" />
      </LayoutWithHeaderBar>
    </Router>

    {/* 
        must come *after* <Router> else Reach router will call focus() 
        on the matched route after action is called, undoing the behaviour!
    */}
    <OnRouteChange action={() => { window.scrollTo(0, 0) } />
  </>
)
0 голосов
/ 11 апреля 2019

Должна быть другая причина, вызывающая это. Как сказал @Vinicius. Потому что для моего приложения primary={false} действительно работает. У меня есть небольшое приложение и мои маршруты ниже.

<Router primary={false}>
  <Home path="/" />
  <Dashboard path="dashboard" />
  <Users path="users" />
  <Sales path="sales" />
  <Settings path="settings" />
</Router>
0 голосов
/ 11 мая 2019

Мне пришлось использовать комбинацию вещей, чтобы это работало. Даже с настройкой primary={false} были случаи, когда страницы не прокручивались до верха.

      <Router primary={false}>
        <ScrollToTop path="/">
          <Home path="/" />
          <Contact path="contact-us" />
          <ThankYou path="thank-you" />
          <WhoWeAre path="who-we-are" />
        </ScrollToTop>
      </Router>

Это основано на Руководстве по восстановлению свитков React Router .

Компонент прокрутки наверх по-прежнему будет работать с вами, у вас нет primary={false}, но он вызывает джанк, с которого он фокусирует маршрут, а затем вызывает window.scrollTo.

// ScrollToTop.js
import React from 'react'

export const ScrollToTop = ({ children, location }) => {
  React.useEffect(() => window.scrollTo(0, 0), [location.pathname])
  return children
}

0 голосов
/ 12 ноября 2018

Попробуйте использовать <Router primary={false}>, который не будет фокусироваться на компоненте маршрута.

https://reach.tech/router/api/Router

первичный: bool

По умолчанию установлено значение true. Первичные маршрутизаторы будут управлять фокусом на переходах местоположения. Если ложь, фокус не будет управляться. Это полезно для маршрутизаторов, отображаемых в виде сторон, заголовков, панировочных сухарей и т. Д., Но не для основного содержимого.

ПРЕДУПРЕЖДЕНИЕ : Если вас беспокоит нарушение доступности, см. Ответ: https://stackoverflow.com/a/56996986/428780

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...