#scroll-top React компонент высшего порядка для управления прокруткой при изменении адреса страницы с помощью react-router 4.x
Содержание
Описание
Данный компонент упрощает управление поведением прокрутки при изменении адреса страницы для разных частей вашего приложения.
Установка
npm
npm install --save-dev gitlab.aic.ru/Nikita_Torchinskiy/scroll-top.git
yarn
yarn add gitlab.aic.ru/Nikita_Torchinskiy/scroll-top.git
Использование
import scrollTop from 'scroll-top'
scrollTop(options)(AmazingReactComponent)
Параметры
Функция scrollTop
принимает объект параметров options
со следующими возможными полями:
(название
: тип
= значение по умолчанию
)
-
scrollOnPathChanges
:boolean
=true
- определяет, будет ли происходить прокрутка, когда меняется путь в адресе страницы. (/somePage
=>/otherPage
) -
scrollOnHashChanges
:boolean
=false
- определяет, будет ли происходить прокрутка, когда меняется хэш в адресе страницы. (/somePage
=>/somePage#someHash
) -
scrollOnSearchChanges
:boolean
=false
- определяет, будет ли происходить прокрутка, когда меняется поисковой запрос в адресе страницы. (/somePage
=>/somePage?param=value
) -
useOnMount
:boolean
=false
- определяет, будет ли использоваться этот компонент сразу же, как только будет смонтирован react (переход со страницы без этого компонента на страницу с этим компонентом). -
top
:number
=0
- смещение от верха страницы (или элемента, еслиgetComponentTop
установлен вtrue
) в пикселях, к которому будет происходить прокрутка. -
getComponentTop
:boolean
=false
- если определен какtrue
, то позиция, к которой будет происходить прокрутка, будет определяться верней границей данного элемента на экране. При этом значение параметраtop
будет определять смещение от этой позиции. -
scrollFunction
:function (top: number): void
=(top) => window.scrollTo(0, top)
- функция, производящая прокрутку. Единственным параметром принимаетtop
- отступ (в пикселях) от верха страницы, к которому должна производиться прокрутка. По умолчанию используетсяwindow.scrollTo(0, top)
. -
checkLocation
:function ({ location, match, prevLocation, prevMatch }): boolean
=({ match, prevMatch }) => match.url === prevMatch.url
- функция, определяющая, должен ли данный компонент обрабатывать изменения в адресе страницы, или передать управление вышестоящему компонентуscrollTop
(если имеется). Входной параметр - объект.location
иmatch
- текущие значения location и match из близжайшегоRoute
;prevLocation
иprevMatch
- предыдущие значения соответственно. По умолчанию производится проверкаmatch.url === prevMatch.url
.
Если какой-то из параметров не указан, то для него будет использовано значение по умолчанию. Также options
может быть типа boolean
, тогда он будет использоваться как значение для scrollOnPathChanges
.
Вложенность
Если на странице имеется одновременно несколько компонентов с scrollTop
, то управлять прокруткой будет только самый глубокий по вложенности из них. Однако, если при изменении адреса страницы, для этого компонента проверка checkLocation
вернет false
, то управление перейдет к вышестоящему по вложенности компоненту.
Пример:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router'
import scrollTop from 'scroll-top'
import App from './App'
import SomeComponent from './SomeComponent'
const AppWithScrollTop = scrollTop({
scrollOnPathChanges: true
})(App)
const UserPageWithScrollTop = scrollTop({
scrollOnPathChanges: false,
})(UserPage)
ReactDOM.render(
<BrowserRouter>
<AppWithScrollTop>
<Switch>
<Route path='/user/:id'>
<UserPageWithScrollTop />
</Route>
{/* ... */}
</Switch>
</AppWithScrollTop>
</BrowserRouter>,
document.getElementById('root')
)
В данном примере, нам необходимо, чтобы внутри App
происходила прокрутка при переходе по страницам, однако, внутри UserPage
- наоборот, т.к. там есть вкладки с информацией, которые переключаются при изменении адреса страницы.
Рассмотрим переход по страницам данного примера:
- Когда пользователь в браузере перейдет по пути
/
, ничего не произойдет, т.к. изменения в пути не происходило. - Переход по ссылке на
/about
вызовет прокрутку к началу страницы. - Переход по ссылке на
/user/1
вызовет прокрутку. В параметрах компонентаUserPageWithScrollTop
прокрутка при изменении пути отключена, однако, по умолчанию,useOnMount
=false
, и прокруткой управляет компонентUserPageWithScrollTop
.
Если необходимо на данном этапе успользовать данныйscrollTop
для определения прокрутки, необходимо для компонентаUserPageWithScrollTop
установить параметрuseOnMount
вtrue
. - Переход по ссылке на
/user/2
вызовет прокрутку, т.к. функция по умолчаниюcheckLocation
вернулаfalse
. В данном случаеmatch.url
=/user/2
, аprevMatch.url
=/user/1
. По этому управление передалось вышестоящему компоненту -AppWithScrollTop
- для которого прокрутка включена.
Если для данного этапа (изменение параметровRoute
) не нужно передавать управление вышестоящему компоненту, необходимо установить параметрcheckLocation
как() => true
(или установить другую проверку, которая подходит). - Переход по ссылке
/user/2/some-info
не вызовет прокрутки. Функция по умолчаниюcheckLocation
возвращаетtrue
(match.url
=prevMatch.url
=/user/2
), в параметрах прокрутка отключена. - Переход по ссылке
/
вызовет прокрутку - компонентаUserPageWithScrollTop
уже нет на странице.
Процесс при изменении адреса
Что происходит, когда меняется адрес страницы?
-
Определяется самый глубокий по дереву компонент с
scrollTop
. -
Если этот компонент был смонтирован только что, проверяется, что параметр
useOnMount === true
. Иначе управление передается близжайшему следующему компонентуscrollTop
выше по дереву, и процесс начинается с этого шага (или заканчивается, если выше компонента нет). -
Происходит проверка - вызывается
checkLocation
из параметров этого компонента или заданный по умолчанию. Если проверка вернулаfalse
, управление передается близжайшему следующему компонентуscrollTop
выше по дереву, и процесс начинается с шага 2. (или заканчивается, если выше компонента нет). -
Компонент, дошедший до этой стадии, проверяет следующие утверждения:
-
scrollOnPathChanges === true
и изменился путь в адресе -
scrollOnHashChanges === true
и изменился хэш в адресе -
scrollOnSearchChanges === true
и изменился поисковой запрос в адресе
Если хотя-бы одно из этих утверждений верно, происходит прокрутка страницы. Иначе процесс заканчивается.
-
Особенности
- При первой загрузке страницы (или обновления) "процесс при изменении адреса" не запускается, и прокрутки никогда не происходит.
- Если компонент был смонтирован только что, то в процессе изменения адреса в аргументах проверочной функции
checkLocation
предыдущие и текущие значения будут равны (prevMatch === match
,prevLocation === location
). - Не используйте компоненты с
scrollTop
не вложенными друг в друга в дереве - иначе работать будет только один из них.