How can I navigate to an anchor in Angular 7

一个人想着一个人 提交于 2020-07-17 10:43:07

问题


I've enable the anchorScrolling in routingModule and all the path but when i click on links nothing happened.

'nav-bar.component.html'

<div id="mySidenav" class="sidenav" #sidenav>
   <a href="javascript:void(0)" class="closeBtn" 
   (click)="closeNav()">&times;</a>
   <a routerLink="/hazyMinds" [fragment]="'HazyMinds'">HazyMinds</a>
   <a routerLink="/ourGames" [fragment]="'Games'">Our Games</a>
   <a routerLink="/contact" [fragment]="'Contact'">Contact</a>
</div>
<span id="openNavBtn"  (click)="openNav()" #openBtn>&#9776;</span>



'app.component.html'

<app-nav-bar></app-nav-bar>
<app-hazy-minds id="HazyMinds"></app-hazy-minds>
<app-games id="Games" ></app-games>
<app-contact id="Contact"></app-contact>
<router-outlet></router-outlet>



'app-routing.module.ts'

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';

import {ContactComponent} from './contact/contact.component';
import {GamesComponent} from './games/games.component';
import {HazyMindsComponent} from './hazy-minds/hazy-minds.component';

const routes: Routes = [
  {path: '', redirectTo: '/', pathMatch: 'full'},
  {path: 'hazyMinds', component : HazyMindsComponent},
  {path: 'ourGames', component : GamesComponent},
  {path: 'contact', component : ContactComponent}
];

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


export class AppRoutingModule { }

I expect that when i clicked on link it automatically scroll to the correct anchor.
Someone know what's wrong with my code? thanks


回答1:


You can use fragments for this:

this.router.navigate(['/results'], { fragment: 'top' });

//

<h1 id="top">asdasd</h1>

https://angular.io/api/router/NavigationExtras




回答2:


So, I just spent like an hour on this with the latest Angular and other solutions worked OK for initial navigation but no matter what I tried, I could not get the anchor scrolling to work with navigation history.

In other words, when I went "back" or "forward" in my browser, the URL would update but I could not get Angular to scroll to the proper place. From logging, it seems that Angular was not actually acknowledging the fragment when going back/forward and so the scrolling was not being triggered.

I got fed up and decided to subscribe to the URL and manually scroll when a fragment is found, here's the code:

ngOnInit() {
  this.router.events.subscribe(val => {
    if (val instanceof NavigationEnd) {
      let fragmentIdx = val.urlAfterRedirects.lastIndexOf('#');
      if (fragmentIdx >= 0 && fragmentIdx < val.urlAfterRedirects.length - 1) {
        let fragment = val.urlAfterRedirects.substring(fragmentIdx+1);
        console.log('fragment: ' + fragment);
        document.getElementById(fragment).scrollIntoView();
      }
    }
  })
}

Just for clarity, you have to specify an id for the target element to scroll to.

Also, here's what my link looks like (for initial navigation):

<a routerLink="." fragment="anchor-name">Scroll To Anchor</a>

Now, I can visit different anchors and see the scrolling as I go back/forward in history. Hope it helps someone!

EDIT:

I have refactored this into its own service with a single method that I call from the ngOnInit of any page/component where I want anchor scrolling. I changed the settings in the main app module back to defaults as this is essentially doing things manually.

Here's the service:

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

@Injectable({
  providedIn: 'root'
})
export class AnchorScrollerService {

  constructor(private router: Router) { }

  listen() {
    this.router.events.subscribe(val => {
      // console.log(val);
      if (val instanceof NavigationEnd) {
        let fragmentIdx = val.urlAfterRedirects.lastIndexOf('#');
        if (fragmentIdx >= 0 && fragmentIdx < val.urlAfterRedirects.length - 1) {
          let fragment = val.urlAfterRedirects.substring(fragmentIdx+1);
          // console.log('fragment: ' + fragment);
          document.getElementById(fragment).scrollIntoView();
        }
      }
    })
  }
}

Now just call listen in your page's ngOnInit():

ngOnInit() {
  this.anchorScrollerService.listen();
}

Also, keep in mind that the latest Chrome has a bug with anchor scrolling that I'm seeing on initial navigation. Subsequent navigation/history works and all is perfect in, say, Firefox. Worth noting though in case you are having Chrome frustrations...you're not alone!



来源:https://stackoverflow.com/questions/53855195/how-can-i-navigate-to-an-anchor-in-angular-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!