programing

Angular 5 루트를 클릭할 때마다 맨 위로 스크롤합니다.

jooyons 2023. 3. 31. 22:02
반응형

Angular 5 루트를 클릭할 때마다 맨 위로 스크롤합니다.

Angular 5를 쓰고 있어요.대시보드는 콘텐츠가 작은 섹션과 콘텐츠가 너무 큰 섹션이 거의 없기 때문에 맨 위로 이동할 때 라우터를 변경할 때 문제가 발생합니다.위로 이동하려면 스크롤해야 합니다.

이 문제를 해결하려면 어떻게 해야 하나요?라우터를 변경할 때 뷰가 항상 맨 위에 유지되도록 해야 하나요?

몇 가지 해결 방법이 있습니다.모두 확인해 주세요:)


옵션 1:

는, 「」를 합니다.activate를 실행할 수 있습니다. 이 새로운 컴포넌트를 사용할 수 .(activate)를 들어) 맨 .

app.component.module

<router-outlet (activate)="onActivate($event)"></router-outlet>

app.component.ts

onActivate(event) {
   // window.scroll(0,0);

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

    //or document.body.scrollTop = 0;
    //or document.querySelector('body').scrollTo(0,0)
    ...
}

Safari에서는 스무스 스크롤이 잘 구현되지 않기 때문에 스무스 스크롤을 위해 예를 들어 다음과 같은 솔루션을 사용합니다.

onActivate(event) {
    let scrollToTop = window.setInterval(() => {
        let pos = window.pageYOffset;
        if (pos > 0) {
            window.scrollTo(0, pos - 20); // how far to scroll on each step
        } else {
            window.clearInterval(scrollToTop);
        }
    }, 16);
}

컴포넌트가 을 트리거하는 .선택하고 스크롤을 것은 .★★★★★★★★★★★★★★★★★★★★★★★★★,if하다

onActivate(e) {
    if (e.constructor.name)==="login"{ // for example
            window.scroll(0,0);
    }
}

옵션 2:

6.부터는 Angular 6.1을 사용할 .{ scrollPositionRestoration: 'enabled' }모든 루트에 적용됩니다.

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

또, 벌써 부드럽게 스크롤 할 수 있습니다.단, 이것은 모든 라우팅에서 수행하는데 불편합니다.


옵션 3:

또 다른 해결책은 라우터의 애니메이션 상단을 스크롤하는 것입니다.맨 위로 스크롤할 모든 전환에서 이 항목을 추가합니다.

query(':enter, :leave', style({ position: 'fixed' }), { optional: true }) 

에서 이 Angular 6의 파라미터를 하여 수정할 수 있습니다.scrollPositionRestoration: 'enabled'app-routing.module.ts의 RouterModule로 합니다.

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

편집: Angular 6+의 경우, Nimesh Nishara Indimagedara의 답변을 사용해 주세요.

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

원답:

모든 작업이 실패하면 템플릿(또는 상위 템플릿)에서 id="top"으로 맨 위에 빈 HTML 요소(예: div)를 만듭니다.

<div id="top"></div>

컴포넌트:

  ngAfterViewInit() {
    // Hack: Scrolls to top of Page after page view initialized
    let top = document.getElementById('top');
    if (top !== null) {
      top.scrollIntoView();
      top = null;
    }
  }

6.에는 Angular 6.1을 사용할 수 있는 이 내장되어 scrollPositionRestoration★★★★★★ 。

Angular 2 Scroll to top on Route Change에 대한 답변을 참조하십시오.

Angular Version 6+부터는 window.scroll(0,0)을 사용할 필요가 없습니다.

버전의 Angular 6+@docs부터
이치노

interface ExtraOptions {
  enableTracing?: boolean
  useHash?: boolean
  initialNavigation?: InitialNavigation
  errorHandler?: ErrorHandler
  preloadingStrategy?: any
  onSameUrlNavigation?: 'reload' | 'ignore'
  scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'
  anchorScrolling?: 'disabled' | 'enabled'
  scrollOffset?: [number, number] | (() => [number, number])
  paramsInheritanceStrategy?: 'emptyOnly' | 'always'
  malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree
  urlUpdateStrategy?: 'deferred' | 'eager'
  relativeLinkResolution?: 'legacy' | 'corrected'
}

scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'

예:

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

해야 하는 에는 No use use use use under use under and to and and and and and and and and and and and and 。window.scroll(0,0)대신 Angular V6에서 공통 패키지가 도입되었습니다.

abstract class ViewportScroller {
  static ngInjectableDef: defineInjectable({ providedIn: 'root', factory: () => new BrowserViewportScroller(inject(DOCUMENT), window) })
  abstract setOffset(offset: [number, number] | (() => [number, number])): void
  abstract getScrollPosition(): [number, number]
  abstract scrollToPosition(position: [number, number]): void
  abstract scrollToAnchor(anchor: string): void
  abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void
}

사용법은 매우 간단합니다.예:

import { Router } from '@angular/router';
import {  ViewportScroller } from '@angular/common'; //import
export class RouteService {

  private applicationInitialRoutes: Routes;
  constructor(
    private router: Router;
    private viewPortScroller: ViewportScroller//inject
  )
  {
   this.router.events.pipe(
            filter(event => event instanceof NavigationEnd))
            .subscribe(() => this.viewPortScroller.scrollToPosition([0, 0]));
}

@Vega는 질문에 대한 직접적인 답변을 제공하지만 문제가 있습니다.브라우저의 뒤로/앞으로 버튼이 파손됩니다.사용자가 브라우저의 뒤로 또는 앞으로 버튼을 클릭하면 위치가 손실되고 맨 위에서 스크롤됩니다.사용자가 링크로 이동하기 위해 아래로 스크롤해야 할 경우 스크롤 막대가 맨 위로 리셋되어 있는 것을 발견하기 위해 뒤로 클릭하는 것만으로 문제가 발생할 수 있습니다.

여기 그 문제에 대한 저의 해결책이 있습니다.

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

내 경우, 나는 그냥 추가했다.

window.scroll(0,0);

ngOnInit()정상적으로 동작하고 있습니다.

각도 6.1 이후:

옵션과 함께 Angular 6.1+에서 사용할 수 있는 내장 솔루션을 사용할 수 있습니다.scrollPositionRestoration: 'enabled'같은 목표를 달성합니다.

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

각도 6.0 이전:

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

주의: 예상 동작은 페이지로 돌아가면 링크를 클릭했을 때와 같은 위치로 스크롤된 상태로 유지되지만 모든 페이지에 도착했을 때는 맨 위로 스크롤됩니다.

콘센트에 및 ), it mat-sidenav를 ID를 합니다.<router-outlet id="main-content" (activate)="onActivate($event)"> 이 하여 맨 위 ' 'mat-sidenav-content'onActivate(event) { document.querySelector("mat-sidenav-content").scrollTo(0, 0); }

위의 어느 것도 어떤 이유로든 작동하지 않았습니다./ 그래서 저는 위의 상위 요소에 요소 ref를 추가했습니다.app.component.html , , , , 입니다.(activate)=onNavigate($event)router-outlet.

<!--app.component.html-->
<div #topScrollAnchor></div>
<app-navbar></app-navbar>
<router-outlet (activate)="onNavigate($event)"></router-outlet>

다음 에 app.component.ts 했습니다.ElementRef

export class AppComponent  {
  @ViewChild('topScrollAnchor') topScroll: ElementRef;

  onNavigate(event): any {
    this.topScroll.nativeElement.scrollIntoView({ behavior: 'smooth' });
  }
}

스택블리츠의 코드는 다음과 같습니다.

이 돼요.app.module.ts 삭제:

RouterModule.forRoot(routes, {
    scrollPositionRestoration: 'enabled' //scroll to the top
})

저는 Angular 11.1.4를 사용하고 있는데, 이 기능은 저에게 효과가 있습니다.

스크롤 기능을 찾고 있는 분들을 위해 기능을 추가하고 필요할 때 언제든지 호출할 수 있습니다.

scrollbarTop(){

  window.scroll(0,0);
}

저는 AngularJS에 있는 것처럼 이 문제에 대한 임베디드 솔루션을 계속 찾고 있습니다.하지만 그때까지 이 솔루션은 단순하고 뒤로 가기 버튼 기능을 유지합니다.

app.component.module

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

zurfyx 오리지널 게시물에서 답변

화면 스크롤을 조정하는 기능만 만들면 됩니다.

예를들면

window.scroll(0,0) OR window.scrollTo() by passing appropriate parameter.

window.scrollTo(xpos, ypos) --> 예상 파라미터.

나에게 효과가 있던 솔루션:

document.getElementsByClassName('layout-content')[0].scrollTo(0, 0);

각도 8, 9, 10으로 작동해요.

덧붙이기만 하면 된다

window.scrollTo({ top: 0 });

로로 합니다.ngOnInit()

다음은 각 컴포넌트를 처음 방문하는 경우에만 컴포넌트 맨 위로 스크롤하는 솔루션입니다(컴포넌트마다 다른 작업을 수행해야 하는 경우).

각 컴포넌트:

export class MyComponent implements OnInit {

firstLoad: boolean = true;

...

ngOnInit() {

  if(this.firstLoad) {
    window.scroll(0,0);
    this.firstLoad = false;
  }
  ...
}

이것을 시험해 보세요.

app.component.ts

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
import {filter} from 'rxjs/operators';
import {Subscription} from 'rxjs';

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

    constructor(private router: Router) {
    }

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

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

export class AppComponent {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
      if (val instanceof NavigationEnd) {
        window.scrollTo(0, 0);
      }
    });
  }

}

컴포넌트: 템플릿에서 액션을 작성하는 대신 모든 라우팅 이벤트를 서브스크라이브하고 Navigation End B/c를 스크롤합니다.그렇지 않으면 잘못된 내비게이션이나 차단된 경로 등에서 이 작업이 발생합니다.이것은 루트가 정상적으로 네비게이트 되었을 경우, 수스 스크롤을 할 수 있는 확실한 방법입니다.그렇지 않으면 아무것도 하지 마세요.

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

  router$: Subscription;

  constructor(private router: Router) {}

  ngOnInit() {
    this.router$ = this.router.events.subscribe(next => this.onRouteUpdated(next));
  }

  ngOnDestroy() {
    if (this.router$ != null) {
      this.router$.unsubscribe();
    }
  }

  private onRouteUpdated(event: any): void {
    if (event instanceof NavigationEnd) {
      this.smoothScrollTop();
    }
  }

  private smoothScrollTop(): void {
    const scrollToTop = window.setInterval(() => {
      const pos: number = window.pageYOffset;
      if (pos > 0) {
          window.scrollTo(0, pos - 20); // how far to scroll on each step
      } else {
          window.clearInterval(scrollToTop);
      }
    }, 16);
  }

}

HTML

<router-outlet></router-outlet>

이거 먹어봐

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

이 코드는 각도 6<=을 지원했습니다.

Just Add(추가만 가능)

 ngAfterViewInit() {
  window.scroll(0,0)
 }
<p class="text-center" (click)="scrollToTop()"> Back to top
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-up-short" viewBox="0 0 16 16">
  <path fill-rule="evenodd" d="M8 12a.5.5 0 0 0 .5-.5V5.707l2.146 2.147a.5.5 0 0 0 .708-.708l-3-3a.5.5 0 0 0-.708 0l-3 3a.5.5 0 1 0 .708.708L7.5 5.707V11.5a.5.5 0 0 0 .5.5z"/>
</svg>
</p>


scrollToTop(): void {
window.scroll(0, 0);
}

언급URL : https://stackoverflow.com/questions/48048299/angular-5-scroll-to-top-on-every-route-click

반응형