[routing] 페이지 앵커에 해시 태그를 사용하는 Angular2 라우팅

내 Angular2 페이지에 몇 가지 링크를 추가하고 싶습니다. 클릭하면 일반 해시 태그처럼 해당 페이지 내의 특정 위치로 이동 합니다. 따라서 링크는 다음과 같습니다.

/users/123#userInfo
/users/123#userPhoto
/users/123#userLikes

기타

나는 일반적인 Angular2 방식으로 괜찮 기 때문에 HashLocationStrategy가 필요하다고 생각하지 않지만 직접 추가하면 링크가 실제로 동일한 페이지의 어딘가가 아닌 루트로 이동합니다. 어떤 방향 으로든 감사합니다.



답변

최신 정보

이제 지원됩니다.

<a [routerLink]="['somepath']" fragment="Test">Jump to 'Test' anchor </a>
this._router.navigate( ['/somepath', id ], {fragment: 'test'});

스크롤하려면 구성 요소에 아래 코드를 추가하십시오.

  import {ActivatedRoute} from '@angular/router'; // <-- do not forget to import

  private fragment: string;

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
  }

  ngAfterViewInit(): void {
    try {
      document.querySelector('#' + this.fragment).scrollIntoView();
    } catch (e) { }
  }

실물

이것은 알려진 문제이며 https://github.com/angular/angular/issues/6595 에서 추적됩니다.


답변

Günter의 대답 은 정확 하지만 앵커 태그 부분으로 “점프”하는 부분은 다루지 않습니다 .

따라서 다음에 추가로 :

<a [routerLink]="['somepath']" fragment="Test">Jump to 'Test' anchor </a>
this._router.navigate( ['/somepath', id ], {fragment: 'test'});

… “점프”동작이 필요한 구성 요소 (부모)에 다음을 추가합니다.

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

class MyAppComponent {
  constructor(router: Router) {

    router.events.subscribe(s => {
      if (s instanceof NavigationEnd) {
        const tree = router.parseUrl(router.url);
        if (tree.fragment) {
          const element = document.querySelector("#" + tree.fragment);
          if (element) { element.scrollIntoView(true); }
        }
      }
    });

  }
}

이것은 해결 방법입니다 . 향후 업데이트를 위해이 github 문제 를 따르십시오 . 크레딧 빅터 Savkin 솔루션을 제공!


답변

조금 늦게 대답해서 죄송합니다. Angular Routing Documentation에는 해시 태그를 페이지 앵커로 라우팅하는 데 도움이되는 미리 정의 된 기능이 있습니다. 예 : anchorScrolling : ‘enabled’

단계 -1 :- 먼저 app.module.ts 파일에서 RouterModule 을 가져옵니다 .

imports:[
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(routes,{
      anchorScrolling: 'enabled'
    })
  ],

2 단계 : -HTML 페이지로 이동하여 탐색을 만들고 [routerLink] 와 같은 두 가지 중요한 속성을 추가 하고 각 Div ID 를 일치시키기 위해 조각 을 추가합니다 .

<ul>
    <li> <a [routerLink] = "['/']"  fragment="home"> Home </a></li>
    <li> <a [routerLink] = "['/']"  fragment="about"> About Us </a></li>
  <li> <a [routerLink] = "['/']"  fragment="contact"> Contact Us </a></li>
</ul>

3 단계 : -ID 이름조각 과 일치시켜 섹션 / div를 만듭니다 .

<section id="home" class="home-section">
      <h2>  HOME SECTION </h2>
</section>

<section id="about" class="about-section">
        <h2>  ABOUT US SECTION </h2>
</section>

<section id="contact" class="contact-section">
        <h2>  CONTACT US SECTION </h2>
</section>

참고로 문제를 해결하는 데 도움이되는 작은 데모를 만들어 아래 예제를 추가했습니다.

데모 : https://routing-hashtag-page-anchors.stackblitz.io/


답변

조금 늦었지만 여기에 작동하는 답변이 있습니다.

<a [routerLink]="['/path']" fragment="test" (click)="onAnchorClick()">Anchor</a>

그리고 구성 요소에서 :

constructor( private route: ActivatedRoute, private router: Router ) {}

  onAnchorClick ( ) {
    this.route.fragment.subscribe ( f => {
      const element = document.querySelector ( "#" + f )
      if ( element ) element.scrollIntoView ( element )
    });
  }

위의 내용은 이미 앵커가있는 페이지에 도달하면 뷰로 자동으로 스크롤되지 않으므로 ngInit에서도 위의 솔루션을 사용하여 함께 작동 할 수 있습니다.

ngOnInit() {
    this.router.events.subscribe(s => {
      if (s instanceof NavigationEnd) {
        const tree = this.router.parseUrl(this.router.url);
        if (tree.fragment) {
          const element = document.querySelector("#" + tree.fragment);
          if (element) { element.scrollIntoView(element); }
        }
      }
    });
  }

구성 요소의 시작 부분에서 Router, ActivatedRoute 및 NavigationEnd를 가져와야합니다.

출처


답변

이전 답변 중 어느 것도 나를 위해 일하지 않았습니다. 마지막 도랑 노력에서 내 템플릿을 시도했습니다.

<a (click)="onClick()">From Here</a>
<div id='foobar'>To Here</div>

내 .ts에서 이것으로 :

onClick(){
    let x = document.querySelector("#foobar");
    if (x){
        x.scrollIntoView();
    }
}

그리고 내부 링크에 대해 예상대로 작동합니다. 실제로 앵커 태그를 사용하지 않으므로 URL을 전혀 건드리지 않습니다.


답변

위의 솔루션이 저에게 효과적이지 않았습니다.

먼저 ngAfterViewChecked ()MyAppComponent 에서 자동 스크롤을 준비하십시오 .

import { Component, OnInit, AfterViewChecked } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

@Component( {
   [...]
} )
export class MyAppComponent implements OnInit, AfterViewChecked {

  private scrollExecuted: boolean = false;

  constructor( private activatedRoute: ActivatedRoute ) {}

  ngAfterViewChecked() {

    if ( !this.scrollExecuted ) {
      let routeFragmentSubscription: Subscription;

      // Automatic scroll
      routeFragmentSubscription =
        this.activatedRoute.fragment
          .subscribe( fragment => {
            if ( fragment ) {
              let element = document.getElementById( fragment );
              if ( element ) {
                element.scrollIntoView();

                this.scrollExecuted = true;

                // Free resources
                setTimeout(
                  () => {
                    console.log( 'routeFragmentSubscription unsubscribe' );
                    routeFragmentSubscription.unsubscribe();
                }, 1000 );

              }
            }
          } );
    }

  }

}

그런 다음 해시 태그 my-app-route보내기로 이동합니다.prodID

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

@Component( {
   [...]
} )
export class MyOtherComponent {

  constructor( private router: Router ) {}

  gotoHashtag( prodID: string ) {
    this.router.navigate( [ '/my-app-route' ], { fragment: prodID } );
  }

}


답변

다른 모든 답변은 Angular 버전 <6.1에서 작동합니다. 그러나 최신 버전을 가지고 있다면 Angular가 문제를 해결 했으므로 이러한 추악한 해킹을 할 필요가 없습니다.

문제에 대한 링크는 다음과 같습니다.

여러분이해야 할 일은 method scrollOffset의 두 번째 인자 옵션으로 설정 하는 것뿐입니다 RouterModule.forRoot.

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      scrollPositionRestoration: 'enabled',
      anchorScrolling: 'enabled',
      scrollOffset: [0, 64] // [x, y]
    })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}