Angular2 Routing dengan Hashtag ke halaman jangkar


120

Saya ingin menambahkan beberapa tautan di halaman Angular2 saya, yang ketika diklik, akan melompat ke posisi tertentu dalam halaman itu, seperti yang dilakukan oleh hashtag biasa. Jadi tautannya akan seperti ini

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

dll.

Saya tidak berpikir saya membutuhkan HashLocationStrategy, karena saya baik-baik saja dengan cara Angular2 normal, tetapi jika saya menambahkan secara langsung, tautannya sebenarnya akan melompat ke root, bukan di suatu tempat di halaman yang sama. Segala arah dihargai, terima kasih.

Jawaban:


130

Memperbarui

Ini sekarang didukung

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

Tambahkan kode di bawah ini ke komponen Anda untuk menggulir

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

Asli

Ini adalah masalah yang diketahui dan dilacak di https://github.com/angular/angular/issues/6595


1
@invot variabel dengan string (misalnya apa yang 123ada dalam pertanyaan) dengan asumsi bahwa jalur rute mengharapkan parameter seperti{ path: 'users/:id', ....}
Günter Zöchbauer

2
Jika Anda ingin menggulir ke jangkar, lihat posting ini: github.com/angular/angular/issues/6595
Pere Pages

12
Catatan: ini masih tidak bergulir
Martín Coll

2
ya itu berfungsi dengan setTimeout, jika saya menemukan solusi yang lebih baik saya akan memberi tahu Anda
Amr Ibrahim

1
Bagi mereka yang berjuang untuk menggulir ke id seperti angka, ingat, itu 01atau 100bukan pemilih CSS yang valid. Anda mungkin ingin menambahkan surat atau sesuatu untuk membuatnya menjadi pemilih yang valid. Jadi, Anda masih akan lulus 01sebagai fragmen, tetapi idharus seperti d01dan karenanya document.querySelector('#d'+id)akan cocok.
pop

52

Meskipun jawaban Günter benar, namun tidak mencakup "lompat ke" bagian tag jangkar .

Oleh karena itu, tambahan untuk:

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

... di komponen (induk) tempat Anda memerlukan perilaku "lompat ke", tambahkan:

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

  }
}

Harap dicatat bahwa ini adalah solusi ! Ikuti masalah github ini untuk pembaruan di masa mendatang. Penghargaan untuk Victor Savkin karena telah memberikan solusinya!


halo, saya membuat halaman FAQ di mana Anda dapat melompat ke jawaban dengan mengklik pertanyaan yang ditentukan dalam daftar di bagian atas halaman. Jadi pengguna sudah berada di halaman saat ini ketika dia melompat ke jangkar. Jika saya ingin atribut routerLink berfungsi, saya harus memberikan "['../faq']"nilainya atau ia akan mencoba melompat ke / faq / faq / # anchor, insteaf dari / faq / # anchor. Apakah ini cara yang benar untuk melakukannya atau adakah cara yang lebih elegan untuk merujuk ke halaman saat ini di routerlink? Juga, document.querySelector("#" + tree.fragment);memberi saya kesalahan pemilih yang bukan valid. Apakah Anda yakin ini benar? Terima kasih
Maurice

2
ketika Anda mengklik lagi pada link yang sama itu tidak berfungsi. Apakah ada yang membuat ini berfungsi jika pengguna mengklik tautan jangkar yang sama <a [routerLink]="['/faq']" fragment="section6">?
Junior Mayhé

@JuniorM Apakah Anda pernah memikirkan hal ini? Saya mengalami masalah yang sama.
The Muffin Man


1
Ini membutuhkan lebih banyak eksposur. Ini adalah jawaban IMO yang lebih baik. Kebanyakan orang ingin melompat ke bagian tersebut.
iamtravisw

45

Maaf sudah terlambat menjawabnya; Ada fungsi yang telah ditentukan sebelumnya di Angular Routing Documentation yang membantu kita dalam melakukan routing dengan hashtag to page anchor yaitu, anchorScrolling: 'enabled'

Langkah-1: - Pertama Impor RouterModule di file app.module.ts: -

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

Langkah-2: - Buka Halaman HTML, Buat navigasi dan tambahkan dua atribut penting seperti [routerLink] dan fragmen untuk mencocokkan ID Div masing-masing : -

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

Langkah-3: - Buat bagian / div dengan mencocokkan nama ID dengan fragmen : -

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

Untuk referensi Anda, saya telah menambahkan contoh di bawah ini dengan membuat demo kecil yang membantu menyelesaikan masalah Anda.

Demo: https://routing-hashtag-page-anchors.stackblitz.io/


Terimakasih banyak untuk ini. Bersih, ringkas, dan berhasil!
Belmiris

2
Ya, Terima kasih, untuk scoll otomatis pada pemuatan halaman dengan Angular 7, cukup tambahkan di scrollPositionRestoration: 'enabled',bawah opsi anchorScrolling :)
Mickaël

Ini menambahkan hash ke akhir url saya dengan benar, tetapi tidak mengikat ke div dengan nama yang sama. Saya tidak yakin apa yang saya lewatkan. Saya mengikuti tiga langkah di atas.
oaklandrichie

@oaklandrichie: Bisakah Anda membagikan kode jsfiddle / stackblitz di sini. Saya dapat membantu Anda
Naheed Shareef

jawaban ini pasti harus diterima, bekerja seperti pesona!
Ciuman Koppány

25

Sedikit terlambat, tetapi inilah jawaban yang menurut saya berhasil:

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

Dan di komponen:

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

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

Hal di atas tidak secara otomatis menggulir ke tampilan jika Anda membuka halaman dengan jangkar, jadi saya menggunakan solusi di atas di ngInit saya sehingga bisa bekerja dengan itu juga:

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

Pastikan untuk mengimpor Router, ActivatedRoute dan NavigationEnd di awal komponen Anda dan semuanya akan berjalan lancar.

Sumber


4
Bekerja untuk saya! Jika Anda ingin menavigasi dalam halaman yang sama dengan yang sudah Anda buka, gunakan [routerLink] = "['.']"
Raoul

1
bisakah anda menjelaskan lebih lanjut? bagian ini document.querySelector ( "#" + f )memberi saya kesalahan karena mengharapkan pemilih, bukan string.
Maurice

1
@ Maurice bagi saya ini berfungsi: element.scrollIntoView()(tanpa meneruskan elementke fungsi). Untuk membuat halus, gunakan ini: element.scrollIntoView({block: "end", behavior: "smooth"}).
Tn. B.

Intellisense sini menunjukkan bahwa dalam onAnchorClick(), kita harus melewati boolean ke scrollIntoView: if (element) { element.scrollIntoView(true); }. Sekarang saya dapat mengklik dua kali pada tautan yang sama dan karya gulir
Junior Mayhé

18

Tak satu pun dari jawaban sebelumnya berhasil untuk saya. Dalam upaya terakhir, saya mencoba di template saya:

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

Dengan ini di .ts saya:

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

Dan berfungsi seperti yang diharapkan untuk tautan internal. Ini sebenarnya tidak menggunakan tag jangkar sehingga tidak akan menyentuh URL sama sekali.


1
sederhana dan mudah
WasiF

6

Solusi di atas tidak berhasil untuk saya ... Yang ini berhasil:

Pertama, persiapkan MyAppComponentuntuk pengguliran otomatis di ngAfterViewChecked () ...

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

              }
            }
          } );
    }

  }

}

Kemudian, navigasikan untuk my-app-routemengirim prodIDhashtag

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

}

Down voting tanpa komentar atau penjelasan ... itu bukan praktik yang baik ...
JavierFuentes

Ini berhasil untuk saya! Mengapa menggunakan ngAfterViewChecked daripada ngInit?
Antoine Boisier-Michaud

Terima kasih @ AntoineBoisier-Michaud atas umpan balik positif Anda. ngInit tidak selalu menyala yang saya butuhkan dalam proyek saya ... ngAfterViewChecked melakukannya. Bisakah Anda memberi suara positif pada solusi ini? Terima kasih.
JavierFuentes

6

Semua jawaban lainnya akan bekerja pada versi Angular <6.1. Tetapi jika Anda memiliki versi terbaru maka Anda tidak perlu melakukan peretasan jelek ini karena Angular telah memperbaiki masalahnya.

berikut ini tautan untuk menerbitkannya

Yang perlu Anda lakukan adalah disetel scrollOffsetdengan opsi RouterModule.forRootmetode argumen kedua .

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

2
apakah ini akan berfungsi untuk tautan luar? katakan dari situs web lain saya klik www.abc.com # sectionToScrollTo
Sushmit Sagar

anchorScrolling tidak berfungsi, jika Anda menggunakan * ngIf secara ekstensif, karena melompat ke awal :-(
Jojo.Lechelt

Satu-satunya masalah yang saya hadapi adalah pengaturan waktu - ini cenderung melompat ke jangkar sebelum gaya beberapa elemen menjadi render penuh, menyebabkan pemosisian menjadi tidak aktif. Akan lebih baik jika Anda bisa menambahkan penundaan :)
Charly

5

Gunakan ini untuk modul router di app-routing.module.ts:

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    useHash: true,
    scrollPositionRestoration: 'enabled',
    anchorScrolling: 'enabled',
    scrollOffset: [0, 64]
  })],
  exports: [RouterModule]
})

Ini akan ada di HTML Anda:

<a href="#/users/123#userInfo">

4

Dalam file html:

<a [fragment]="test1" [routerLink]="['./']">Go to Test 1 section</a>

<section id="test1">...</section>
<section id="test2">...</section>

Dalam file ts:

export class PageComponent implements AfterViewInit, OnDestroy {

  private destroy$$ = new Subject();
  private fragment$$ = new BehaviorSubject<string | null>(null);
  private fragment$ = this.fragment$$.asObservable();

  constructor(private route: ActivatedRoute) {
    this.route.fragment.pipe(takeUntil(this.destroy$$)).subscribe(fragment => {
      this.fragment$$.next(fragment);
    });
  }

  public ngAfterViewInit(): void {
    this.fragment$.pipe(takeUntil(this.destroy$$)).subscribe(fragment => {
      if (!!fragment) {
        document.querySelector('#' + fragment).scrollIntoView();
      }
    });
  }

  public ngOnDestroy(): void {
    this.destroy$$.next();
    this.destroy$$.complete();
  }
}

QuerySelector dapat dengan mudah dimasukkan ke dalam perintah bernama scrolllTo. Url akan menjadi <a scrollTo="test1" [routerLink]="['./']"> Buka bagian Tes 1 </a>
John Peters

3

Karena properti fragmen masih tidak menyediakan pengguliran jangkar, solusi ini berhasil bagi saya:

<div [routerLink]="['somepath']" fragment="Test">
  <a href="#Test">Jump to 'Test' anchor </a>
</div>

3

Menambah jawaban Kalyoyan , langganan ini terikat ke router dan akan aktif sampai halaman tersebut sepenuhnya di-refresh. Saat berlangganan acara router dalam sebuah komponen, pastikan untuk berhenti berlangganan di ngOnDestroy:

import { OnDestroy } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { Subscription } from "rxjs/Rx";

class MyAppComponent implements OnDestroy {

  private subscription: Subscription;

  constructor(router: Router) {
    this.subscription = 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(element); }
        }
      }
    });
  }

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

Saya pikir langganan untuk acara rute secara otomatis dirobohkan.

3

Saya baru saja membuat ini berfungsi di situs web saya sendiri, jadi saya pikir akan bermanfaat untuk memposting solusi saya di sini.

<a [routerLink]="baseUrlGoesHere" fragment="nameOfYourAnchorGoesHere">Link Text!</a>

<a name="nameOfYourAnchorGoesHere"></a>
<div>They're trying to anchor to me!</div>

Dan kemudian di komponen Anda, pastikan Anda menyertakan ini:

 import { ActivatedRoute } from '@angular/router';

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

Saya pikir lebih baik menulis saja element.scrollIntoView()atau element.scrollIntoView(true). Versi Anda tidak dapat dikompilasi untuk saya (mungkin karena strictNullChecks?).
David L.

3

Setelah membaca semua solusi, saya mencari komponen dan saya menemukan satu yang melakukan persis seperti yang diminta pertanyaan asli: menggulir ke tautan jangkar. https://www.npmjs.com/package/ng2-scroll-to

Saat Anda menginstalnya, Anda menggunakan sintaks seperti:

// app.awesome.component.ts
@Component({
   ...
   template: `...
        <a scrollTo href="#main-section">Scroll to main section</a>
        <button scrollTo scrollTargetSelector="#test-section">Scroll to test section</a>
        <button scrollTo scrollableElementSelector="#container" scrollYTarget="0">Go top</a>
        <!-- Further content here -->
        <div id="container">
            <section id="main-section">Bla bla bla</section>
            <section id="test-section">Bla bla bla</section>
        <div>
   ...`,
})
export class AwesomeComponent {
}

Ini telah bekerja dengan sangat baik untuk saya.


Gunakan roda, jangan menemukannya lagi;)
Yogen Rai

Pernahkah Anda melihat kode di balik komponen itu? Kelihatannya sangat rapuh - proyek ini juga memiliki 14 masalah terbuka - yang mencakup hal-hal seperti elemen tidak ada, target null, tidak menggulir ke elemen, masalah dukungan browser.
Drenai

tidak berfungsi ketika Anda memiliki anak (anak memiliki entitas berlabuh dan / atau nama jangkar) di komponen induk, itu hanya menyegarkan halaman
Sasha Bond

3

Solusi sederhana yang berfungsi untuk halaman tanpa parameter kueri apa pun, adalah browser mundur / maju, sesuai dengan router dan tautan dalam.

<a (click)="jumpToId('anchor1')">Go To Anchor 1</a>


ngOnInit() {

    // If your page is dynamic
    this.yourService.getWhatever()
        .then(
            data => {
            this.componentData = data;
            setTimeout(() => this.jumpToId( window.location.hash.substr(1) ), 100);
        }
    );

    // If your page is static
    // this.jumpToId( window.location.hash.substr(1) )
}

jumpToId( fragment ) {

    // Use the browser to navigate
    window.location.hash = fragment;

    // But also scroll when routing / deep-linking to dynamic page
    // or re-clicking same anchor
    if (fragment) {
        const element = document.querySelector('#' + fragment);
        if (element) element.scrollIntoView();
    }
}

Batas waktu hanya untuk memungkinkan halaman memuat data dinamis apa pun yang "dilindungi" oleh * ngIf. Ini juga dapat digunakan untuk menggulir ke bagian atas halaman saat mengubah rute - cukup berikan tag anchor atas default.


2

jika tidak masalah untuk menambahkan id elemen ke url, Anda harus mempertimbangkan untuk melihat tautan ini:

Angular 2 - Tautan Jangkar ke Elemen di Halaman Saat Ini

// html
// add (click) event on element
<a (click)="scroll({{any-element-id}})">Scroll</a>

// in ts file, do this
scroll(sectionId) {
let element = document.getElementById(sectionId);

  if(element) {
    element.scrollIntoView(); // scroll to a particular element
  }
 }


1

Berikut adalah solusi lain dengan referensi ke jawaban JavierFuentes:

<a [routerLink]="['self-route', id]" fragment="some-element" (click)="gotoHashtag('some-element')">Jump to Element</a>

dalam naskah:

import {ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs/Subscription";

export class Links {
    private scrollExecuted: boolean = false;

    constructor(private route: ActivatedRoute) {} 

    ngAfterViewChecked() {
            if (!this.scrollExecuted) {
              let routeFragmentSubscription: Subscription;
              routeFragmentSubscription = this.route.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();
                      }, 0);
                  }
                }
              });
            }
          }

        gotoHashtag(fragment: string) {
            const element = document.querySelector("#" + fragment);
            if (element) element.scrollIntoView(element);
        }
}

Ini memungkinkan pengguna untuk langsung menggulir ke elemen, jika pengguna langsung membuka halaman yang memiliki hashtag di url.

Tetapi dalam kasus ini, saya telah berlangganan Fragmen rute ngAfterViewCheckedtetapi ngAfterViewChecked()dipanggil terus menerus per setiap ngDoCheckdan itu tidak memungkinkan pengguna untuk menggulir kembali ke atas, jadirouteFragmentSubscription.unsubscribe dipanggil setelah batas waktu 0 milidetik setelah tampilan digulir ke elemen.

Selain itu, gotoHashtagmetode didefinisikan untuk menggulir ke elemen ketika pengguna secara khusus mengklik tag jangkar.

Memperbarui:

Jika url memiliki string kueri, [routerLink]="['self-route', id]"di jangkar tidak akan mempertahankan string kueri. Saya mencoba solusi berikut untuk hal yang sama:

<a (click)="gotoHashtag('some-element')">Jump to Element</a>

constructor( private route: ActivatedRoute,
              private _router:Router) {
}
...
...

gotoHashtag(fragment: string) {
    let url = '';
    let urlWithSegments = this._router.url.split('#');

    if(urlWithSegments.length){
      url = urlWithSegments[0];
    }

    window.location.hash = fragment;
    const element = document.querySelector("#" + fragment);
    if (element) element.scrollIntoView(element);
}

1

Yang ini berhasil untukku !! NgFor ini jadi tag jangkar secara dinamis, Anda harus menunggu mereka merender

HTML:

<div #ngForComments *ngFor="let cm of Comments">
    <a id="Comment_{{cm.id}}" fragment="Comment_{{cm.id}}" (click)="jumpToId()">{{cm.namae}} Reply</a> Blah Blah
</div>

File ts saya:

private fragment: string;
@ViewChildren('ngForComments') AnchorComments: QueryList<any>;

ngOnInit() {
      this.route.fragment.subscribe(fragment => { this.fragment = fragment; 
   });
}
ngAfterViewInit() {
    this.AnchorComments.changes.subscribe(t => {
      this.ngForRendred();
    })
}

ngForRendred() {
    this.jumpToId()
}

jumpToId() { 
    let x = document.querySelector("#" + this.fragment);
    console.log(x)
    if (x){
        x.scrollIntoView();
    }
}

Jangan lupa untuk mengimpor itu ViewChildren, QueryListdll .. dan menambahkan beberapa konstruktor ActivatedRoute!!


1

Tidak seperti jawaban yang lain saya juga juga menambahkan focus()bersama dengan scrollIntoView(). Juga saya gunakan setTimeoutkarena melompat ke atas jika tidak saat mengubah URL. Tidak yakin apa alasannya tetapi tampaknya setTimeoutada solusinya.

Asal:

<a [routerLink] fragment="some-id" (click)="scrollIntoView('some-id')">Jump</a>

Tujuan:

<a id="some-id" tabindex="-1"></a>

Naskah:

scrollIntoView(anchorHash) {
    setTimeout(() => {
        const anchor = document.getElementById(anchorHash);
        if (anchor) {
            anchor.focus();
            anchor.scrollIntoView();
        }
    });
}

1

Saya memiliki masalah yang sama. Solusinya: menggunakan View port Scroller https://angular.io/api/common/ViewportScroller#scrolltoanchor

- kode app-routing.module.ts:

import { PageComponent } from './page/page.component';

const routes: Routes = [
   path: 'page', component: PageComponent },
   path: 'page/:id', component: PageComponent }
];

- Komponen HTML

  <a (click) = "scrollTo('typeExec')">
    <mat-icon>lens</mat-icon>
  </a>

- Kode komponen:

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


    export class ParametrageComponent {

      constructor(private viewScroller: ViewportScroller) {}

      scrollTo(tag : string)
      {
        this.viewScroller.scrollToAnchor(tag);
      }

    }

0

Saya baru saja menguji plugin yang sangat berguna yang tersedia di nmp - ngx-scroll-to , yang sangat cocok untuk saya. Namun ini dirancang untuk Angular 4+, tetapi mungkin seseorang akan menemukan jawaban ini bermanfaat.


0

Saya mencoba sebagian besar solusi ini tetapi mengalami masalah saat keluar dan kembali dengan fragmen lain yang tidak berhasil, jadi saya melakukan sesuatu yang sedikit berbeda yang berfungsi 100%, dan menyingkirkan hash jelek di URL.

tl; dr inilah cara yang lebih baik dari yang pernah saya lihat sejauh ini.

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

@Component({
    selector: 'app-hero',
    templateUrl: './hero.component.html',
    styleUrls: ['./hero.component.scss']
})
export class HeroComponent implements OnInit, AfterViewChecked, OnDestroy {
    private fragment: string;
    fragSub: Subscription;

    constructor(private route: ActivatedRoute) { }

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

    ngAfterViewChecked(): void {
        try {
            document.querySelector('#' + this.fragment).scrollIntoView({behavior: 'smooth'});
            window.location.hash = "";
          } catch (e) { }
    }

    ngOnDestroy() {
        this.fragSub.unsubscribe();
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.