Açısal 2 Güzergah değişikliğinde yukarı çık


296

Açısal 2 uygulamamda bir sayfayı aşağı kaydırdığımda ve sayfanın altındaki bağlantıya tıkladığımda rotayı değiştirir ve sonraki sayfayı alır, ancak sayfanın en üstüne gitmez. Sonuç olarak, ilk sayfanın uzunluğu uzunsa ve 2. sayfanın içeriği azsa, 2. sayfanın içeriğinden yoksun olduğu izlenimi verir. İçindekiler yalnızca kullanıcı sayfanın üst kısmına geçerse görünür.

Bileşeni ngInit olarak pencereyi sayfanın en üstüne kaydırabilirim, ancak uygulamamdaki tüm rotaları otomatik olarak ele alabilecek daha iyi bir çözüm var mı?


20
Açısal 6.1'den beri, hevesle yüklenen modüllerde veya sadece app.module'de {scrollPositionRestoration: 'etkin'} kullanabiliriz ve tüm rotalara uygulanacaktır. RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
Nisan 19'da Manwal

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

bir kişi odaktan bahsetmedi mi? erişilebilirliği / ekran okuyucuları düzgün bir şekilde desteklemek her zamankinden daha önemlidir ve odaklanmayı düşünmeden en üste kaydırırsanız, sonraki sekme tuşuna basıldığında ekranın altına atlanabilir.
Simon_Weaver

Yanıtlar:


386

Bir rota değişikliği dinleyicisini ana bileşeninize kaydedebilir ve rota değişikliklerinin en üstüne gelebilirsiniz.

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)daha özlü document.body.scrollTop = 0;ve daha okunabilir bir IMO'dur.
Mark E. Haase

10
Bunu uyguladıktan sonra bile, Iphone'un safari tarayıcısında sorunun devam ettiğini fark eden var mı? Düşüncesi olan var mı?
rgk

1
@mehaase Görünüşe göre cevabınız en iyisi. window.body.scrollTop Firefox masaüstünde benim için çalışmıyor. Çok teşekkür ederim!
KCarnaille

3
Bu benim için çalıştı, ancak varsayılan "geri" düğmesi davranışını kırar. Geri gitmek, önceki kaydırma konumunu hatırlamalıdır.
JackKalish

6
Bu çalıştı !! Her ne kadar üste yumuşak kaydırmayı canlandırmak $("body").animate({ scrollTop: 0 }, 1000);yerine ekledimwindow.scrollTo(0, 0)
Manubhargav

360

Açısal 6.1 ve üstü :

Açısal 6.1 (2018-07-25'de yayınlandı), "Yönlendirici Kaydırma Konumu Restorasyonu" adlı bir özellik aracılığıyla bu sorunu çözmek için yerleşik destek ekledi. Resmi Angular blogunda açıklandığı gibi , bunu aşağıdaki gibi yönlendirici yapılandırmasında etkinleştirmeniz gerekir:

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

Ayrıca blog, "Bunun ilerideki bir büyük sürümde varsayılan olması bekleniyor" ifadesini kullandı. Şimdiye kadar bu olmadı (Açısal 8.2'den itibaren), ancak sonunda kodunuzda hiçbir şey yapmanız gerekmeyecek ve bu sadece kutunun dışında düzgün çalışacaktır.

Bu özellik ve bu dokümanın nasıl özelleştirileceği hakkında daha fazla ayrıntıyı resmi dokümanlarda görebilirsiniz .

Açısal 6.0 ve öncesi :

@ GuilhermeMeireles'in mükemmel yanıtı orijinal sorunu giderirken, geri veya ileri gittiğinizde (tarayıcı düğmeleriyle veya koddaki Konum aracılığıyla) beklediğiniz normal davranışı ortadan kaldırarak yeni bir sorun ortaya çıkarır. Beklenen davranış, sayfaya geri döndüğünüzde, bağlantıyı tıklattığınızda aynı konuma doğru kaydırılmış olarak kalması, ancak her sayfaya ulaştığınızda en üste kaydırmanın açıkça bu beklentiyi kırmasıdır.

Aşağıdaki kod, Konum'un PopStateEvent sekansına abone olarak ve yeni gelen sayfa bu tür bir olaydan kaynaklanıyorsa başa dön mantığını atlayarak bu tür gezinmeyi algılamak için mantığı genişletir.

Geri döndüğünüz sayfa tüm görünümü kaplayacak kadar uzunsa, kaydırma konumu otomatik olarak geri yüklenir, ancak @JordanNelson'un doğru şekilde işaret ettiği gibi, sayfa daha kısaysa orijinal y kaydırma konumunu izlemeniz ve geri yüklemeniz gerekir açıkça sayfaya geri döndüğünüzde. Kodun güncellenmiş sürümü, kaydırma konumunu her zaman açıkça geri yükleyerek bu durumu da kapsar.

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
Bu, doğrudan uygulama bileşenine veya içinde kullanılan tek bir bileşene (ve dolayısıyla tüm uygulama tarafından paylaşılır) gitmelidir. Örneğin, bir üst gezinme çubuğu bileşenine ekledim. Tüm bileşenlerinize dahil etmemelisiniz.
Fernando Echeverria

3
Bunu yapabilirsiniz ve kodu diğer, tarayıcı olmayan platformlarla daha geniş uyumlu hale getirecektir. Bkz stackoverflow.com/q/34177221/2858481 uygulama ayrıntıları için.
Fernando Echeverria

3
Modern tarayıcılarda geri / ileri düğmesini tıklar ve basılı tutarsanız, hemen önceki / sonraki konumunuz dışındaki konumlara gitmenizi sağlayan bir menü görünür. Bunu yaparsanız bu çözüm kırılır. Çoğu için bir kenar durum, ancak söz etmeye değer.
adamdport


1
Yuvalanmış öğeler için "Yönlendirici Kaydırma Konumu Restorasyonunu" etkinleştirmenin bir yolu var mı, yoksa yalnızca şunlar için bodymi çalışıyor ?
vulp

61

Açısal 6.1'den, artık güçlüğü önleyebilir ve ikinci bir parametre olarak extraOptionskendinize geçebilirsiniz RouterModule.forRoot()ve scrollPositionRestoration: enabledAngular'a rota değiştiğinde yukarı gitmesini söyleyebilirsiniz.

Varsayılan olarak bunu şurada bulabilirsiniz 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 { }

Açısal Resmi Belgeler


3
Yukarıdaki cevap daha açıklayıcı olsa da, bu cevabın tam olarak nereye gitmesi gerektiğini söyledim
ryanovas

32

Gözlenebilir filteryöntemden yararlanarak bunu daha özlü bir şekilde yazabilirsiniz :

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

Açısal Malzeme 2 sidenavını kullanırken yukarı kaydırma sorunları yaşıyorsanız, bu yardımcı olacaktır. Pencere veya belge gövdesinde kaydırma çubuğu yoktur, bu nedenle sidenaviçerik kabını almanız ve o öğeyi kaydırmanız gerekir, aksi takdirde pencereyi varsayılan olarak kaydırmayı deneyin.

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

Ayrıca, Açısal CDK v6.x'te artık kaydırma işlemine yardımcı olabilecek bir kaydırma paketi bulunmaktadır .


2
Harika! Benim için çalıştı -document.querySelector('.mat-sidenav-content .content-div').scrollTop = 0;
Amir Tugi

Güzel bir adam ... mtpultz & @AmirTugi. Şu anda bununla başa çıkmak, ve sen benim için çivilenmişsin, şerefe! Muhtemelen kaçınılmaz olarak kendi yan nav'ımı yuvarlayacaktır, çünkü md-araç çubuğu pozisyon: sabit (üstte) olduğunda Malzeme 2'ler iyi oynamaz. Siz fikriniz olmadığı sürece .... ????
Tim Harker

Cevabımı bulabilirdim ... stackoverflow.com/a/40396105/3389046
Tim Harker

16

Sunucu tarafı oluşturma işleminiz varsa, kodu windowsbu değişkenin mevcut olmadığı sunucuda kullanarak çalıştırmamaya dikkat edin . Kod kırılmasına neden olur.

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();
  }
}

isPlatformBrowseruygulamanın oluşturulduğu geçerli platformun bir tarayıcı olup olmadığını kontrol etmek için kullanılan bir işlevdir. Enjekte ettikplatformId .

Değişken varlığını kontrol etmek windows, güvende olmak, şöyle mümkündür:

if (typeof window != 'undefined')

1
Eğer enjekte gerek yok PLATFORM_IDiçinde constructorve de parametre olarak bu değer vermek isPlatformBrowseryöntemle?
Poul Kruijt

1
@PierreDuc Evet, cevap yanlış. isPlatformBrowserbir işlevdir ve her zaman doğrudur. Şimdi düzenledim.
Lazar Ljubenović

Teşekkürler! Şimdi doğru! API'yı yeni doğruladım: github.com/angular/angular/blob/…
Raptor

13

tıklama işlemi ile kolayca yapın

ana bileşeninizde html başvuru yapın #scrollContainer

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

ana bileşen .ts

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

Kaydırılacak öğe scrollContainerilk düğümde olmayabilir, nesneyi biraz kazmanız gerekebilir, benim için gerçekten işe yarayan şey buyduscrollContainer .scrollable._elementRef.nativeElement.scrollTop = 0
Byron Lopez

13

Açısal son zamanlarda yeni bir özellik tanıttı, açısal yönlendirme modülü içinde aşağıdaki gibi değişiklikler yapın

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

12

En iyi yanıt Açısal GitHub tartışmasında bulunur ( Rotayı değiştirmek yeni sayfada yukarı kaymaz ).

Belki sadece kök yönlendirici değişikliklerinde en üste gitmek istersiniz (çocuklarda değil, çünkü bir sekme içinde tembel yük içeren yolları yükleyebilirsiniz)

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'e tam kredi ( orijinal gönderi )



7

Açısal 6.1'den itibaren, yönlendirici adlı bir yapılandırma seçeneği sunarscrollPositionRestoration , bu, bu senaryoyu karşılamak için tasarlanmıştır.

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

4

Sayfayı en üste kaydırmanız gerekiyorsa, bunu yapabilirsiniz (en iyi çözüm değil, hızlı)

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

4

İşte benim bulduğum bir çözüm. LocationStrategy'yi Yönlendirici olaylarıyla eşleştirdim. Bir kullanıcının şu anda tarayıcı geçmişinde ne zaman geçiş yaptığını bilmek için bir boole ayarlamak için LocationStrategy'yi kullanma. Bu şekilde, bir grup URL ve y-scroll verisini depolamak zorunda değilim (her veri URL'ye göre değiştirildiği için zaten iyi çalışmıyor). Bu, bir kullanıcı bir tarayıcıda geri veya ileri düğmesini basılı tutmaya karar verdiğinde ve yalnızca bir sayfa yerine birden fazla sayfa ileri veya geri gittiğinde kenar durumunu da çözer.

PS Sadece IE, Chrome, FireFox, Safari ve Opera'nın en son sürümünü test ettim (bu yazı itibariyle).

Bu yardımcı olur umarım.

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

Bu çözüm @ FernandoEcheverria ve @ GuilhermeMeireles'in çözümüne dayanmaktadır, ancak daha özlüdür ve Açısal Yönlendiricinin sağladığı popstate mekanizmalarla çalışır. Bu, birden fazla ardışık gezinmenin kaydırma düzeyinin kaydedilmesini ve geri yüklenmesini sağlar.

Her navigasyon durumu için kaydırma konumlarını bir haritada saklarız scrollLevels. Bir popstate olay, Açısal Router tarafından sağlanan restore edilmek üzere devlet kimliği yoktur kez: event.restoredState.navigationId. Bu daha sonra bu durumun son kaydırma seviyesini almak için kullanılır scrollLevels.

Rota için kaydedilmiş kaydırma seviyesi yoksa, beklediğiniz gibi en üste kayar.

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);
        }
      }

    });
  }

}

Muhteşem. Ben pencere yerine bir div kaydırmak için biraz özel bir sürüm yapmak zorunda kaldı, ama çalıştı. Temel farklılıklardan biri scrollTopvs idi scrollY.
BBaysinger

4

@Guilherme Meireles tarafından aşağıda gösterilen mükemmel cevaba ek olarak, aşağıda gösterildiği gibi yumuşak kaydırma ekleyerek uygulamanızı düzenleyebilirsiniz

 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)
            });
        }
    }

ardından snippet'i aşağıya ekleyin

 html {
      scroll-behavior: smooth;
    }

stillerinize. css


1

iphone / ios safari için bir set ile sarabilirsiniz

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

benim durumumda css sayfa sarma öğesinin de ayarlanması gerekiyordu; height: 100vh + 1px;
tubbsy

1

Merhaba arkadaşlar bu benim için açısal 4'te çalışıyor. Sadece yönlendirici değişikliğine geçmek için ebeveyne başvurmanız gerekiyor`

layout.component.pug

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

layout.component.ts

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

1
pugon öğrenmek için rahatsız etmem tembellik, ama HTML çevirebilir miyim?
CodyBugstein

0

@Fernando Echeverria harika! ancak bu kod karma yönlendirici veya tembel yönlendiricide çalışmaz. çünkü konum değişikliklerini tetiklemiyorlar. bunu deneyebilir:

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

RouterKendini kullanmak, tutarlı tarayıcı deneyimini sürdürmek için tamamen üstesinden gelemediğiniz sorunlara neden olacaktır. Bence en iyi yöntem, sadece bir özel kullanmak directiveve tıklama üzerine kaydırma sıfırlamak için izin vermektir. Bununla ilgili iyi bir şey, urltıklattığınızla aynı konumdaysanız, sayfanın da en üste geri kaymasıdır. Bu normal web siteleriyle tutarlıdır. Temel directiveşöyle görünebilir:

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

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

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

Aşağıdaki kullanımla:

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

Bu çoğu kullanım durumu için yeterli olacaktır, ancak bundan kaynaklanabilecek birkaç sorun hayal edebiliyorum:

  • universalKullanımı nedeniyle çalışmıyorwindow
  • Her tıklama ile tetiklendiği için değişiklik algılamaya küçük hız etkisi
  • Bu yönergeyi devre dışı bırakmanın bir yolu yok

Bu sorunların üstesinden gelmek aslında oldukça kolaydır:

@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)
      );
    }
  }
}

Bu, çoğu kullanım senaryosunu, temel olanla aynı kullanımla, etkinleştirmek / devre dışı bırakmak avantajını dikkate alır:

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

reklam vermek istemiyorsanız okumayın

Tarayıcının passiveolayları destekleyip desteklemediğini kontrol etmek için başka bir iyileştirme yapılabilir . Bu, kodu biraz daha karmaşıklaştıracaktır ve tüm bunları özel yönergelerinizde / şablonlarınızda uygulamak istiyorsanız biraz belirsizdir. Bu yüzden bu sorunları çözmek için kullanabileceğiniz küçük bir kütüphane yazdım . Yukarıdaki işlevle aynı işleve sahip olmak ve eklenen passiveetkinlikle birlikte , ng-event-optionskitaplığı kullanıyorsanız yönergelerinizi değiştirebilirsiniz . Mantık click.pnbdinleyicinin içindedir :

@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

Bu, karma navigasyon dahil tüm navigasyon değişiklikleri için benim için en iyi sonucu verdi

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

Bu kodun arkasındaki ana fikir, ziyaret edilen tüm URL'leri bir dizideki ilgili scrollY verileriyle birlikte tutmaktır. Bir kullanıcı sayfayı her terk ettiğinde (NavigationStart) bu dizi güncellenir. Bir kullanıcı her yeni sayfaya girdiğinde (NavigationEnd) Y konumunu geri yüklemeye karar veririz veya bu sayfaya nasıl ulaştığımıza bağlı olarak yapmayız. Eğer bir sayfada refernce kullanılmışsa, 0'a kaydırırız. Tarayıcı geri / ileri özellikleri kullanılmışsa, dizimize kaydedilen Y'ye kaydırırız. İngilizcem için üzgünüm :)

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()Açısal 5'te benim için çalışmıyor, bu yüzden şöyle kullandım document.body.scrollTop,

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

0

Aynı yolla farklı bileşenler yüklüyorsanız, aynı şeyi elde etmek için ViewportScroller'ı kullanabilirsiniz.

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

constructor(private viewportScroller: ViewportScroller) {}

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

0

window scroll top
Hem window.pageYOffset hem de document.documentElement.scrollTop, her durumda aynı sonucu döndürür. window.pageYOffset IE 9 altında desteklenmez.

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>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.