Кутовий 2 Прокрутіть доверху на Зміна маршруту


295

У моєму додатку Angular 2, коли я прокручую сторінку вниз і натискаю посилання внизу сторінки, вона змінює маршрут і переносить мене на наступну сторінку, але вона не прокручується вгору сторінки. Як результат, якщо перша сторінка довга, а друга сторінка має мало вмісту, створюється враження, що на 2-й сторінці не вистачає вмісту. Оскільки вміст видно лише в тому випадку, якщо користувач прокручує верхню частину сторінки.

Я можу прокрутити вікно вгору сторінки в ngInit компонента, але чи є краще рішення, яке може автоматично обробляти всі маршрути в моєму додатку?


20
Оскільки Angular 6.1, ми можемо використовувати {scrollPositionRestoration: 'enable'} на охоче завантажених модулях або просто в app.module, і він буде застосований до всіх маршрутів. RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
Manwal

Muito obrigado sua solução funcionou perfeitamente para mim :)
Raphael

ні одна людина не згадала фокус? важливіше, ніж будь-коли раніше, належним чином підтримувати доступність / зчитувачі екрану, і якщо ви просто прокручуєте до верху, не враховуючи фокус, наступна клавіша вкладки може перейти до нижньої частини екрана.
Simon_Weaver

Відповіді:


385

Ви можете зареєструвати слухача зміни маршруту на своєму головному компоненті та прокрутити до версії зміни маршруту.

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';

@Component({
    selector: 'my-app',
    template: '<ng-content></ng-content>',
})
export class MyAppComponent implements OnInit {
    constructor(private router: Router) { }

    ngOnInit() {
        this.router.events.subscribe((evt) => {
            if (!(evt instanceof NavigationEnd)) {
                return;
            }
            window.scrollTo(0, 0)
        });
    }
}

11
window.scrollTo(0, 0)є більш стислим, ніж document.body.scrollTop = 0;ІМО, і більш читаним.
Марк Е. Хааз

10
Хтось зауважив, що навіть після втілення цього питання у веб-переглядачі сафарі Iphone зберігається проблема. якісь думки?
rgk

1
@mehaase Схоже, ваша відповідь найкраща. window.body.scrollTop не працює для мене на робочому столі Firefox. Тож дякую!
KCarnaille

3
Це працювало для мене, але воно порушує поведінку кнопки "назад" за замовчуванням. Повертаючись назад, слід пам'ятати попереднє положення прокрутки.
JackKalish

6
Це спрацювало !! Хоча я додав, $("body").animate({ scrollTop: 0 }, 1000);а не window.scrollTo(0, 0)анімувати плавне прокручування до верху
Manubhargav

360

Кутовий 6.1 і пізніші :

Кутова 6.1 (випущена 2018-07-25) додала вбудовану підтримку для вирішення цієї проблеми через функцію під назвою "Відновлення позиції прокрутки маршрутизатора". Як описано в офіційному блозі Angular , вам потрібно просто включити це в конфігурації маршрутизатора так:

RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'})

Крім того, у блозі йдеться про "очікується, що це стане дефолтом у майбутньому великому випуску". Поки що цього не сталося (як у Angular 8.2), але в кінцевому підсумку вам нічого не потрібно буде робити взагалі у вашому коді, і це просто працюватиме правильно.

Більш детальну інформацію про цю функцію та про те, як налаштувати таку поведінку, можна переглянути в офіційних документах .

Кутовий 6.0 і новіші :

Хоча чудова відповідь @ GuilhermeMeireles виправляє оригінальну проблему, вона вводить нову, порушуючи нормальну поведінку, яку ви очікуєте, коли ви рухаєтесь назад або вперед (за допомогою кнопок браузера або через Location у коді). Очікувана поведінка полягає в тому, що коли ви повертаєтесь до сторінки, вона повинна залишатись прокрученою донизу до того самого місця, яке було, коли ви натискали на посилання, але прокручування до вершини, коли ви приїжджаєте на кожну сторінку, явно порушує це очікування.

Нижче наведений код розширює логіку виявлення подібного типу навігації, підписавшись на послідовність PopStateEvent Location і пропустивши логіку прокрутки до верху, якщо нещодавно прибула сторінка є результатом такої події.

Якщо сторінка, з якої ви переходите назад, достатньо довга, щоб охопити весь вікно перегляду, положення прокрутки відновлюється автоматично, але як правильно вказав @JordanNelson, якщо сторінка коротша, вам слід відслідковувати початкове положення y прокрутки та відновити її явно, коли ви повернетесь до сторінки. Оновлена ​​версія коду охоплює і цей випадок, завжди явно відновлюючи положення прокрутки.

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { Location, PopStateEvent } from "@angular/common";

@Component({
    selector: 'my-app',
    template: '<ng-content></ng-content>',
})
export class MyAppComponent implements OnInit {

    private lastPoppedUrl: string;
    private yScrollStack: number[] = [];

    constructor(private router: Router, private location: Location) { }

    ngOnInit() {
        this.location.subscribe((ev:PopStateEvent) => {
            this.lastPoppedUrl = ev.url;
        });
        this.router.events.subscribe((ev:any) => {
            if (ev instanceof NavigationStart) {
                if (ev.url != this.lastPoppedUrl)
                    this.yScrollStack.push(window.scrollY);
            } else if (ev instanceof NavigationEnd) {
                if (ev.url == this.lastPoppedUrl) {
                    this.lastPoppedUrl = undefined;
                    window.scrollTo(0, this.yScrollStack.pop());
                } else
                    window.scrollTo(0, 0);
            }
        });
    }
}

2
Це повинно входити або в компонент додатка безпосередньо, або в один компонент, який використовується в ньому (і тому поділяється всім додатком). Наприклад, я включив його в основний компонент панелі навігації. Ви не повинні включатись у всі свої компоненти.
Фернандо Ехеверрія

3
Ви можете це зробити, і це зробить код більш сумісним з іншими, не браузерними, платформами. Докладні відомості див. У розділі stackoverflow.com/q/34177221/2858481 .
Фернандо Ехеверрія

3
Якщо натиснути і утримувати кнопку назад / вперед у сучасних браузерах, з’явиться меню, яке дозволяє переходити до інших місць, окрім безпосередньо попереднього / наступного. Це рішення порушується, якщо ви це зробите. Це більшість випадків, але варто згадати.
admdport


1
Чи є спосіб увімкнути "Відновлення позиції прокрутки маршрутизатора" для вкладених елементів або це працює лише для body?
vulp

61

З кутового 6.1 тепер ви можете уникнути клопоту і перейти extraOptionsдо свого RouterModule.forRoot()як другий параметр і можете вказатиscrollPositionRestoration: enabled щоб повідомити Angular прокручуватися до верху, коли маршрут змінюється.

За замовчуванням ви знайдете це в app-routing.module.ts:

const routes: Routes = [
  {
    path: '...'
    component: ...
  },
  ...
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled', // Add options right here
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Кутові офіційні документи


3
Хоча відповідь вище є більш описовою, мені подобається, що ця відповідь мені точно сказала, куди це потрібно йти
ryanovas

32

Ви можете написати це більш лаконічно, скориставшись спостережуваним filterметодом:

this.router.events.filter(event => event instanceof NavigationEnd).subscribe(() => {
      this.window.scrollTo(0, 0);
});

Якщо у вас виникають проблеми з прокруткою до вершини під час використання кутових матеріалів 2, це допоможе. У корпусі вікна чи документа не буде панелі прокрутки, тому вам потрібно отримати sidenavконтейнер вмісту та прокрутити цей елемент, інакше спробуйте прокрутити вікно за замовчуванням.

this.router.events.filter(event => event instanceof NavigationEnd)
  .subscribe(() => {
      const contentContainer = document.querySelector('.mat-sidenav-content') || this.window;
      contentContainer.scrollTo(0, 0);
});

Крім того, Angular CDK v6.x має пакет прокрутки, який може допомогти в роботі з прокруткою.


2
Чудово! Для мене це працювало -document.querySelector('.mat-sidenav-content .content-div').scrollTop = 0;
Амір Тугі

Хороший один хлопці ... в mtpultz & @AmirTugi. Справа з цим зараз, і ти прибив це для мене, ура! Можливо, неминуче в кінцевому підсумку буде прокат моєї власної сторони nav, оскільки Матеріал 2 не грає добре, коли md-панель інструментів є позицією: фіксовано (вгорі). Якщо ви, хлопці, не маєте ідей .... ????
Тім Харкер

Можливо, я знайшов свою відповідь ... stackoverflow.com/a/40396105/3389046
Тім Харкер

16

Якщо у вас є серверне візуалізація, ви повинні бути обережними, щоб не запустити код windowsна сервері, де ця змінна не існує. Це призведе до порушення коду.

export class AppComponent implements OnInit {
  routerSubscription: Subscription;

  constructor(private router: Router,
              @Inject(PLATFORM_ID) private platformId: any) {}

  ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
      this.routerSubscription = this.router.events
        .filter(event => event instanceof NavigationEnd)
        .subscribe(event => {
          window.scrollTo(0, 0);
        });
    }
  }

  ngOnDestroy() {
    this.routerSubscription.unsubscribe();
  }
}

isPlatformBrowser- це функція, яка використовується для перевірки, чи поточна платформа, на якій надано додаток, - це браузер чи ні. Ми даємо йому ін’єкцію platformId.

Можна також перевірити наявність змінної windows, щоб бути безпечною, як це:

if (typeof window != 'undefined')

1
Чи не потрібно вводити PLATFORM_IDв constructorі давати це значення як параметр у isPlatformBrowserметоді de ?
Poul Kruijt

1
@PierreDuc Так, відповідь неправильна. isPlatformBrowserце функція і завжди буде трибунною. Я зараз це відредагував.
Лазар Любенович

Дякую! Зараз це правильно! Щойно перевірено API: github.com/angular/angular/blob/…
Raptor

13

просто зробіть це легко за допомогою дії клацання

у вашому головному компоненті html зробіть посилання #scrollContainer

<div class="main-container" #scrollContainer>
    <router-outlet (activate)="onActivate($event, scrollContainer)"></router-outlet>
</div>

в основному компоненті .ts

onActivate(e, scrollContainer) {
    scrollContainer.scrollTop = 0;
}

Елемент для прокрутки може бути не в scrollContainerпершому вузлі, можливо, вам доведеться трохи копати об’єкт, для мене те, що він справді працював,scrollContainer .scrollable._elementRef.nativeElement.scrollTop = 0
Байрон Лопес

13

Кутовий останнім часом запровадив нову функцію, всередині кутового модуля маршрутизації вносяться зміни, як нижче

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    scrollPositionRestoration: 'top'
  })],

12

Найкраща відповідь міститься в обговоренні кутового GitHub ( Зміна маршруту не прокручується вгору на новій сторінці ).

Можливо, ви хочете перейти до вершини лише в змінах кореневого маршрутизатора (не у дітей, тому що ви можете завантажувати маршрути з ледачим навантаженням у наборі табулетів)

app.component.html

<router-outlet (deactivate)="onDeactivate()"></router-outlet>

app.component.ts

onDeactivate() {
  document.body.scrollTop = 0;
  // Alternatively, you can scroll to top by using this other call:
  // window.scrollTo(0, 0)
}

Повні кредити JoniJnm ( оригінальна публікація )



7

Як і в Angular 6.1, маршрутизатор пропонує опцію конфігурації, яка називається scrollPositionRestoration, що призначена для задоволення цього сценарію.

imports: [
  RouterModule.forRoot(routes, {
    scrollPositionRestoration: 'enabled'
  }),
  ...
]

4

Якщо вам потрібно просто прокрутити сторінку доверху, ви можете це зробити (не найкраще рішення, але швидко)

document.getElementById('elementId').scrollTop = 0;

4

Ось рішення, яке я придумав. Я поєднав LocationStrategy з подіями маршрутизатора. Використовуючи LocationStrategy, щоб встановити булеве значення, щоб знати, коли користувач в даний час переходить через історію браузера. Таким чином, мені не доведеться зберігати купу даних про URL-адреси та y-прокрутки (що так чи інакше не працює, оскільки кожна інформація замінюється на основі URL-адреси). Це також вирішує крайній випадок, коли користувач вирішує утримувати кнопку назад або вперед у веб-переглядачі і повертається назад або вперед кілька сторінок, а не лише одну.

PS Я протестував лише останню версію IE, Chrome, FireFox, Safari та Opera (станом на цю посаду).

Сподіваюсь, це допомагає.

export class AppComponent implements OnInit {
  isPopState = false;

  constructor(private router: Router, private locStrat: LocationStrategy) { }

  ngOnInit(): void {
    this.locStrat.onPopState(() => {
      this.isPopState = true;
    });

    this.router.events.subscribe(event => {
      // Scroll to top if accessing a page, not via browser history stack
      if (event instanceof NavigationEnd && !this.isPopState) {
        window.scrollTo(0, 0);
        this.isPopState = false;
      }

      // Ensures that isPopState is reset
      if (event instanceof NavigationEnd) {
        this.isPopState = false;
      }
    });
  }
}

4

Це рішення базується на рішенні @ FernandoEcheverria та @ GuilhermeMeireles, але воно є більш стислим і працює з механізмами popstate, які надає кутовий маршрутизатор. Це дозволяє зберігати та відновлювати рівень прокрутки декількох послідовних навігацій.

Ми зберігаємо позиції прокрутки для кожного стану навігації на карті scrollLevels. Як тільки є подія popstate, ідентифікатор держави , який збирається бути відновлений поставляються кутовим Router: event.restoredState.navigationId. Потім використовується для отримання останнього рівня прокрутки цього стануscrollLevels .

Якщо для маршруту немає збереженого рівня прокрутки, він прокручується до вершини, як ви очікували.

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';

@Component({
    selector: 'my-app',
    template: '<ng-content></ng-content>',
})
export class AppComponent implements OnInit {

  constructor(private router: Router) { }

  ngOnInit() {
    const scrollLevels: { [navigationId: number]: number } = {};
    let lastId = 0;
    let restoredId: number;

    this.router.events.subscribe((event: Event) => {

      if (event instanceof NavigationStart) {
        scrollLevels[lastId] = window.scrollY;
        lastId = event.id;
        restoredId = event.restoredState ? event.restoredState.navigationId : undefined;
      }

      if (event instanceof NavigationEnd) {
        if (restoredId) {
          // Optional: Wrap a timeout around the next line to wait for
          // the component to finish loading
          window.scrollTo(0, scrollLevels[restoredId] || 0);
        } else {
          window.scrollTo(0, 0);
        }
      }

    });
  }

}

Дивовижно. Мені довелося зробити трохи користувальницьку версію, щоб прокрутити div, а не вікно, але це спрацювало. Одним з ключових різниця була scrollTopпроти scrollY.
BBaysinger

4

На додаток до ідеальної відповіді, наданої @Guilherme Meireles, як показано нижче, ви можете налаштувати свою реалізацію, додавши плавну прокрутку, як показано нижче

 import { Component, OnInit } from '@angular/core';
    import { Router, NavigationEnd } from '@angular/router';

    @Component({
        selector: 'my-app',
        template: '<ng-content></ng-content>',
    })
    export class MyAppComponent implements OnInit {
        constructor(private router: Router) { }

        ngOnInit() {
            this.router.events.subscribe((evt) => {
                if (!(evt instanceof NavigationEnd)) {
                    return;
                }
                window.scrollTo(0, 0)
            });
        }
    }

потім додайте фрагмент нижче

 html {
      scroll-behavior: smooth;
    }

до ваших styles.css


1

для iphone / ios safari ви можете обгортати setTimeout

setTimeout(function(){
    window.scrollTo(0, 1);
}, 0);

у моєму випадку також потрібно було встановити css елемент для обгортання сторінки; height: 100vh + 1px;
tubbsy

1

Привіт, хлопці, це працює для мене в кутовому 4. Ви просто повинні посилатися на батьків, щоб прокрутити зміни маршрутизатора "

layout.component.pug

.wrapper(#outlet="")
    router-outlet((activate)='routerActivate($event,outlet)')

layout.component.ts

 public routerActivate(event,outlet){
    outlet.scrollTop = 0;
 }`

1
пробачте мою лінь, що не переймаюся навчати мопсів, але чи можете ви перевести на HTML?
CodyBugstein

0

@Fernando Echeverria чудово! але цей код не працює в хеш-роутері або ледачому маршрутизаторі. оскільки вони не ініціюють зміни місцезнаходження. можна спробувати це:

private lastRouteUrl: string[] = []
  

ngOnInit(): void {
  this.router.events.subscribe((ev) => {
    const len = this.lastRouteUrl.length
    if (ev instanceof NavigationEnd) {
      this.lastRouteUrl.push(ev.url)
      if (len > 1 && ev.url === this.lastRouteUrl[len - 2]) {
        return
      }
      window.scrollTo(0, 0)
    }
  })
}


0

Використання самого Routerсебе спричинить проблеми, які ви не можете повністю подолати, щоб підтримувати послідовну роботу браузера. На мою думку, найкращий метод - просто скористатися користувальницьким directiveі дозволити цьому скинути прокрутку при натисканні. Хороша річ у тому, що якщо ви знаходитесь на тому ж url, що ви клацаєте, сторінка також буде прокручуватися назад до верху. Це узгоджується із звичайними веб-сайтами. Основне directiveможе виглядати приблизно так:

import {Directive, HostListener} from '@angular/core';

@Directive({
    selector: '[linkToTop]'
})
export class LinkToTopDirective {

    @HostListener('click')
    onClick(): void {
        window.scrollTo(0, 0);
    }
}

З наступним використанням:

<a routerLink="/" linkToTop></a>

Цього буде достатньо для більшості випадків використання, але я можу уявити кілька проблем, які можуть виникнути з цього приводу:

  • Не працює universal через використанняwindow
  • Мала швидкість впливає на виявлення змін, оскільки вона спрацьовує кожним клацанням
  • Не можна відключити цю директиву

Насправді досить легко подолати ці проблеми:

@Directive({
  selector: '[linkToTop]'
})
export class LinkToTopDirective implements OnInit, OnDestroy {

  @Input()
  set linkToTop(active: string | boolean) {
    this.active = typeof active === 'string' ? active.length === 0 : active;
  }

  private active: boolean = true;

  private onClick: EventListener = (event: MouseEvent) => {
    if (this.active) {
      window.scrollTo(0, 0);
    }
  };

  constructor(@Inject(PLATFORM_ID) private readonly platformId: Object,
              private readonly elementRef: ElementRef,
              private readonly ngZone: NgZone
  ) {}

  ngOnDestroy(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.elementRef.nativeElement.removeEventListener('click', this.onClick, false);
    }
  }

  ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.ngZone.runOutsideAngular(() => 
        this.elementRef.nativeElement.addEventListener('click', this.onClick, false)
      );
    }
  }
}

Це враховує більшість випадків використання з тим же використанням, що і основне, з перевагою включення / відключення:

<a routerLink="/" linkToTop></a> <!-- always active -->
<a routerLink="/" [linkToTop]="isActive"> <!-- active when `isActive` is true -->

рекламні ролики, не читайте, якщо ви не хочете, щоб їх рекламували

Можна також зробити ще одне вдосконалення, щоб перевірити, чи підтримує браузер passiveподії чи ні . Це ще більше ускладнить код і трохи незрозуміло, якщо ви хочете реалізувати все це у своїх спеціальних директивах / шаблонах. Тому я написав невелику бібліотеку, яку ви можете використовувати для вирішення цих проблем. Щоб мати той самий функціонал, що і вище, і з додаванням passiveподії ви можете змінити свою директиву на це, якщо ви використовуєте ng-event-optionsбібліотеку. Логіка всередині click.pnbслухача:

@Directive({
    selector: '[linkToTop]'
})
export class LinkToTopDirective {

    @Input()
    set linkToTop(active: string|boolean) {
        this.active = typeof active === 'string' ? active.length === 0 : active;
    }

    private active: boolean = true;

    @HostListener('click.pnb')
    onClick(): void {
      if (this.active) {
        window.scrollTo(0, 0);
      }        
    }
}

0

Це найкраще працювало для всіх змін навігації, включаючи хеш-навігацію

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  this._sub = this.route.fragment.subscribe((hash: string) => {
    if (hash) {
      const cmp = document.getElementById(hash);
      if (cmp) {
        cmp.scrollIntoView();
      }
    } else {
      window.scrollTo(0, 0);
    }
  });
}

0

Основна ідея цього коду - зберігати всі відвідувані URL-адреси разом із відповідними даними scrollY у масиві. Кожен раз, коли користувач залишає сторінку (NavigationStart), цей масив оновлюється. Кожен раз, коли користувач переходить на нову сторінку (NavigationEnd), ми вирішуємо відновити Y-положення або не залежно від того, як ми потрапимо на цю сторінку. Якщо було використано посилання на деякій сторінці, ми прокручуємо до 0. Якщо використовуються функції назад / вперед браузера, ми прокручуємо до Y, збереженого в нашому масиві. Вибачте за мою англійську :)

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Location, PopStateEvent } from '@angular/common';
import { Router, Route, RouterLink, NavigationStart, NavigationEnd, 
    RouterEvent } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'my-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {

  private _subscription: Subscription;
  private _scrollHistory: { url: string, y: number }[] = [];
  private _useHistory = false;

  constructor(
    private _router: Router,
    private _location: Location) {
  }

  public ngOnInit() {

    this._subscription = this._router.events.subscribe((event: any) => 
    {
      if (event instanceof NavigationStart) {
        const currentUrl = (this._location.path() !== '') 
           this._location.path() : '/';
        const item = this._scrollHistory.find(x => x.url === currentUrl);
        if (item) {
          item.y = window.scrollY;
        } else {
          this._scrollHistory.push({ url: currentUrl, y: window.scrollY });
        }
        return;
      }
      if (event instanceof NavigationEnd) {
        if (this._useHistory) {
          this._useHistory = false;
          window.scrollTo(0, this._scrollHistory.find(x => x.url === 
          event.url).y);
        } else {
          window.scrollTo(0, 0);
        }
      }
    });

    this._subscription.add(this._location.subscribe((event: PopStateEvent) 
      => { this._useHistory = true;
    }));
  }

  public ngOnDestroy(): void {
    this._subscription.unsubscribe();
  }
}

0

window.scrollTo()не працює для мене у Angular 5, тому я використовував document.body.scrollTop,

this.router.events.subscribe((evt) => {
   if (evt instanceof NavigationEnd) {
      document.body.scrollTop = 0;
   }
});

0

Якщо ви завантажуєте різні компоненти одним і тим же маршрутом, ви можете використовувати ViewportScroller, щоб досягти того ж самого.

import { ViewportScroller } from '@angular/common';

constructor(private viewportScroller: ViewportScroller) {}

this.viewportScroller.scrollToPosition([0, 0]);

0

вікно прокрутки вгорі
Обидва window.pageYOffset і document.documentElement.scrollTop повертає однаковий результат у всіх випадках. window.pageYOffset не підтримується нижче IE 9.

app.component.ts

import { Component, HostListener, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  isShow: boolean;
  topPosToStartShowing = 100;

  @HostListener('window:scroll')
  checkScroll() {

    const scrollPosition = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;

    console.log('[scroll]', scrollPosition);

    if (scrollPosition >= this.topPosToStartShowing) {
      this.isShow = true;
    } else {
      this.isShow = false;
    }
  }

  gotoTop() {
    window.scroll({ 
      top: 0, 
      left: 10, 
      behavior: 'smooth' 
    });
  }
}

app.component.html

<style>
  p {
  font-family: Lato;
}

button {
  position: fixed;
  bottom: 5px;
  right: 5px;
  font-size: 20px;
  text-align: center;
  border-radius: 5px;
  outline: none;
}
  </style>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>
<p>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Minus, repudiandae quia. Veniam amet fuga, eveniet velit ipsa repudiandae nemo? Sit dolorem itaque laudantium dignissimos, rerum maiores nihil ad voluptates nostrum.
</p>

<button *ngIf="isShow" (click)="gotoTop()">👆</button>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.