@aic/react-scroll-top v1.0.3
#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
- наоборот, т.к. там есть вкладки с информацией, которые переключаются при изменении адреса страницы.
Рассмотрим переход по страницам данного примера:
1. Когда пользователь в браузере перейдет по пути /
, ничего не произойдет, т.к. изменения в пути не происходило.
2. Переход по ссылке на /about
вызовет прокрутку к началу страницы.
3. Переход по ссылке на /user/1
вызовет прокрутку. В параметрах компонента UserPageWithScrollTop
прокрутка при изменении пути отключена, однако, по умолчанию, useOnMount
= false
, и прокруткой управляет компонент UserPageWithScrollTop
.
Если необходимо на данном этапе успользовать данный scrollTop
для определения прокрутки, необходимо для компонента UserPageWithScrollTop
установить параметр useOnMount
в true
.
4. Переход по ссылке на /user/2
вызовет прокрутку, т.к. функция по умолчанию checkLocation
вернула false
. В данном случае match.url
= /user/2
, а prevMatch.url
= /user/1
. По этому управление передалось вышестоящему компоненту - AppWithScrollTop
- для которого прокрутка включена.
Если для данного этапа (изменение параметров Route
) не нужно передавать управление вышестоящему компоненту, необходимо установить параметр checkLocation
как () => true
(или установить другую проверку, которая подходит).
5. Переход по ссылке /user/2/some-info
не вызовет прокрутки. Функция по умолчанию checkLocation
возвращает true
(match.url
= prevMatch.url
= /user/2
), в параметрах прокрутка отключена.
6. Переход по ссылке /
вызовет прокрутку - компонента UserPageWithScrollTop
уже нет на странице.
Процесс при изменении адреса
Что происходит, когда меняется адрес страницы?
1. Определяется самый глубокий по дереву компонент с scrollTop
.
2. Если этот компонент был смонтирован только что, проверяется, что параметр useOnMount === true
. Иначе управление передается близжайшему следующему компоненту scrollTop
выше по дереву, и процесс начинается с этого шага (или заканчивается, если выше компонента нет).
3. Происходит проверка - вызывается checkLocation
из параметров этого компонента или заданный по умолчанию. Если проверка вернула false
, управление передается близжайшему следующему компоненту scrollTop
выше по дереву, и процесс начинается с шага 2. (или заканчивается, если выше компонента нет).
4. Компонент, дошедший до этой стадии, проверяет следующие утверждения:
scrollOnPathChanges === true
и изменился путь в адресе
scrollOnHashChanges === true
и изменился хэш в адресе
* scrollOnSearchChanges === true
и изменился поисковой запрос в адресе
Если хотя-бы одно из этих утверждений верно, происходит прокрутка страницы. Иначе процесс заканчивается.
Особенности
- При первой загрузке страницы (или обновления) "процесс при изменении адреса" не запускается, и прокрутки никогда не происходит.
- Если компонент был смонтирован только что, то в процессе изменения адреса в аргументах проверочной функции
checkLocation
предыдущие и текущие значения будут равны (prevMatch === match
,prevLocation === location
). - Не используйте компоненты с
scrollTop
не вложенными друг в друга в дереве - иначе работать будет только один из них.