В моем приложении Angular 2, когда я прокручиваю страницу вниз и щелкаю ссылку внизу страницы, она меняет маршрут и переходит на следующую страницу, но не переходит в верхнюю часть страницы. В результате, если первая страница длинная, а на 2-й странице мало содержимого, создается впечатление, что на 2-й странице не хватает содержимого. Так как содержимое видимо только при прокрутке пользователя вверх страницы.
Я могу прокрутить окно до верхней части страницы в ngInit компонента, но есть ли лучшее решение, которое может автоматически обрабатывать все маршруты в моем приложении?
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
Ответы:
Вы можете зарегистрировать прослушиватель изменения маршрута в своем главном компоненте и прокручивать вверх для изменения маршрута.
источник
window.scrollTo(0, 0)
является более краткимdocument.body.scrollTop = 0;
, и более читаемым ИМО.$("body").animate({ scrollTop: 0 }, 1000);
а неwindow.scrollTo(0, 0)
анимировать плавную прокрутку вверхУгловой 6.1 и позже :
В Angular 6.1 (выпущено в 2018-07-25) добавлена встроенная поддержка для решения этой проблемы с помощью функции «Восстановление положения прокрутки маршрутизатора». Как описано в официальном блоге Angular , вам просто нужно включить это в конфигурации маршрутизатора следующим образом:
Кроме того, блог гласит: «Ожидается, что это станет по умолчанию в будущем выпуске». Пока что этого не произошло (по состоянию на Angular 8.2), но в конечном итоге вам вообще не нужно ничего делать в вашем коде, и это будет работать корректно из коробки.
Вы можете увидеть более подробную информацию об этой функции и о том, как настроить это поведение в официальных документах .
Угловой 6.0 и ранее :
Хотя отличный ответ @ GuilhermeMeireles исправляет исходную проблему, он вводит новую, нарушая нормальное поведение, которое вы ожидаете при переходе назад или вперед (с помощью кнопок браузера или с помощью Location в коде). Ожидаемое поведение заключается в том, что при переходе обратно на страницу она должна оставаться прокручиваемой вниз до того же места, в котором она была при нажатии на ссылку, но прокрутка к вершине при переходе на каждую страницу, очевидно, разрушает это ожидание.
Приведенный ниже код расширяет логику для обнаружения такого рода навигации, подписавшись на последовательность PopStateEvent в Location и пропустив логику прокрутки вверх, если вновь появившаяся страница является результатом такого события.
Если страница, с которой вы переходите назад, достаточно длинна, чтобы покрыть весь видовой экран, положение прокрутки восстанавливается автоматически, но, как правильно указал @JordanNelson, если страница короче, вам нужно отслеживать исходную позицию прокрутки y и восстанавливать ее. явно, когда вы вернетесь на страницу. Обновленная версия кода также охватывает этот случай, всегда явно восстанавливая положение прокрутки.
источник
body
?Начиная с Angular 6.1, теперь вы можете избежать хлопот и перейти
extraOptions
к своемуRouterModule.forRoot()
второму параметру, а также можете указатьscrollPositionRestoration: enabled
Angular прокручивать вверх при каждом изменении маршрута.По умолчанию вы найдете это в
app-routing.module.ts
:Angular Официальные Документы
источник
Вы можете написать это более кратко, используя преимущества наблюдаемого
filter
метода:Если у вас возникли проблемы с прокруткой вверх при использовании sidenav Angular Material 2, это поможет. У окна или тела документа не будет полосы прокрутки, поэтому вам нужно получить
sidenav
контейнер содержимого и прокрутить этот элемент, в противном случае попробуйте прокрутить окно по умолчанию.Кроме того, Angular CDK v6.x теперь имеет пакет прокрутки, который может помочь с обработкой прокрутки.
источник
document.querySelector('.mat-sidenav-content .content-div').scrollTop = 0;
Если у вас есть рендеринг на стороне сервера, вы должны быть осторожны, чтобы не запускать код, используемый
windows
на сервере, где эта переменная не существует. Это приведет к взлому кода.isPlatformBrowser
является функцией, используемой для проверки, является ли текущая платформа, на которой отображается приложение, браузером или нет. Мы даем это введеноplatformId
.Это также можно проверить на наличие переменной
windows
, чтобы быть в безопасности, как это:источник
PLATFORM_ID
вconstructor
и давать это значение в качестве параметра вisPlatformBrowser
методе de ?isPlatformBrowser
это функция и всегда будет правдой. Я редактировал это сейчас.просто сделай это легко с помощью щелчка
в вашем основном компоненте HTML сделать ссылку #scrollContainer
в основной компонент .ts
источник
scrollContainer
первом узле, возможно, вам придется немного покопаться в объекте, для меня он действительно работалscrollContainer .scrollable._elementRef.nativeElement.scrollTop = 0
Angular в последнее время представил новую функцию, внутри модуля угловой маршрутизации внести изменения, как показано ниже
источник
Лучший ответ - в обсуждении Angular GitHub ( изменение маршрута не прокручивается вверх на новой странице ).
app.component.html
app.component.ts
Полные кредиты JoniJnm ( оригинальный пост )
источник
Вы можете добавить хук жизненного цикла AfterViewInit к своему компоненту.
источник
Начиная с версии Angular 6.1, маршрутизатор предоставляет опцию конфигурации, которая называется
scrollPositionRestoration
для этого сценария.источник
Если вам нужно просто прокрутить страницу вверх, вы можете сделать это (не лучшее решение, но быстрое)
источник
Вот решение, которое я придумала. Я связал LocationStrategy с событиями Router. Использование LocationStrategy для установки логического значения, чтобы знать, когда пользователь в данный момент просматривает историю браузера. Таким образом, мне не нужно хранить кучу данных URL и y-scroll (что в любом случае не работает, так как все данные заменяются на основе URL). Это также решает крайний случай, когда пользователь решает удерживать кнопку «назад» или «вперед» в браузере и переходит назад или вперед на несколько страниц, а не на одну.
PS Я тестировал только на последних версиях IE, Chrome, FireFox, Safari и Opera (по состоянию на этот пост).
Надеюсь это поможет.
источник
Это решение основано на решениях @ FernandoEcheverria и @ GuilhermeMeireles, но оно более лаконично и работает с механизмами popstate, которые предоставляет Angular Router. Это позволяет сохранять и восстанавливать уровень прокрутки нескольких последовательных переходов.
Мы храним позиции прокрутки для каждого состояния навигации на карте
scrollLevels
. Как только есть событие popstate, идентификатор государства , который собирается быть восстановлен поставляются угловым Router:event.restoredState.navigationId
. Затем он используется для получения последнего уровня прокрутки этого состоянияscrollLevels
.Если для маршрута нет сохраненного уровня прокрутки, он будет прокручиваться вверх, как и следовало ожидать.
источник
scrollTop
противscrollY
.В дополнение к идеальному ответу, предоставленному @Guilherme Meireles, как показано ниже, вы можете настроить свою реализацию, добавив плавную прокрутку, как показано ниже.
затем добавьте фрагмент ниже
в ваши styles.css
источник
для iPhone / IOS Safari вы можете обернуть с помощью setTimeout
источник
height: 100vh + 1px;
Привет, ребята, это работает для меня в angular 4. Вы просто должны сослаться на родителя, чтобы прокрутить изменения маршрутизатора`
layout.component.pug
layout.component.ts
источник
@ Фернандо Эчеверрия отлично! но этот код не работает в хэш-маршрутизаторе или ленивом маршрутизаторе. потому что они не вызывают изменения местоположения. можно попробовать это:
источник
Использование самого
Router
себя вызовет проблемы, которые вы не можете полностью преодолеть, чтобы поддерживать постоянную работу браузера. На мой взгляд, лучший способ - просто использовать кастомdirective
и позволить этому сбросить прокрутку по клику. Хорошая вещь об этом, то, что, если вы находитесь на том же самом,url
что вы нажимаете, страница также будет прокручиваться вверх. Это соответствует нормальным веб-сайтам. Основноеdirective
может выглядеть примерно так:Со следующим использованием:
Этого будет достаточно для большинства вариантов использования, но я могу представить несколько проблем, которые могут возникнуть из этого:
universal
из-за использованияwindow
На самом деле это довольно легко преодолеть эти проблемы:
Это учитывает большинство сценариев использования, при том же использовании, что и основной, с преимуществом включения / выключения:
рекламные ролики, не читайте, если вы не хотите, чтобы вас рекламировали
Еще одно улучшение может быть сделано, чтобы проверить, поддерживает ли браузер
passive
события. Это немного усложнит код и будет немного неясным, если вы захотите реализовать все это в своих пользовательских директивах / шаблонах. Вот почему я написал небольшую библиотеку, которую вы можете использовать для решения этих проблем. Чтобы иметь ту же функциональность, что и выше, и с добавленнымpassive
событием, вы можете изменить свою директиву на эту, если вы используетеng-event-options
библиотеку. Логика внутриclick.pnb
слушателя:источник
Это сработало для меня лучше всего для всех изменений навигации, включая хэш-навигацию
источник
Основная идея этого кода - сохранить все посещенные URL вместе с соответствующими данными scrollY в массиве. Каждый раз, когда пользователь покидает страницу (NavigationStart), этот массив обновляется. Каждый раз, когда пользователь входит на новую страницу (NavigationEnd), мы решаем восстановить позицию Y или нет, в зависимости от того, как мы попадаем на эту страницу. Если использовалась ссылка на какой-либо странице, мы переходим к 0. Если были использованы функции браузера назад / вперед, мы переходим к Y, сохраненному в нашем массиве. Извините за мой английский :)
источник
window.scrollTo()
не работает для меня в Angular 5, поэтому я использовалdocument.body.scrollTop
как,источник
Если вы загружаете разные компоненты по одному и тому же маршруту, вы можете использовать ViewportScroller для достижения того же результата.
источник
Окно прокрутки вверх.
Window.pageYOffset и document.documentElement.scrollTop возвращают одинаковый результат во всех случаях. window.pageYOffset не поддерживается ниже IE 9.
app.component.ts
app.component.html
источник