如何导航到 Angular 7 中的锚点

sam*_*ben 9 anchor routerlink angular

我已经在routingModule 和所有路径中启用了anchorScrolling,但是当我点击链接时什么也没发生。

'导航栏.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>
Run Code Online (Sandbox Code Playgroud)



'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>
Run Code Online (Sandbox Code Playgroud)



'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 { }
Run Code Online (Sandbox Code Playgroud)

我希望当我点击链接时它会自动滚动到正确的锚点。
有人知道我的代码有什么问题吗?谢谢

enn*_*oid 8

您可以为此使用片段:

this.router.navigate(['/results'], { fragment: 'top' });
Run Code Online (Sandbox Code Playgroud)

//

<h1 id="top">asdasd</h1>
Run Code Online (Sandbox Code Playgroud)

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


GoF*_*rth 7

对我来说,其他解决方案对于初始导航来说效果很好,但无论我尝试什么,我都无法让锚点滚动来处理导航历史记录。

换句话说,当我在浏览器中“后退”或“前进”时,URL 会更新,但我无法让 Angular 滚动到正确的位置。从日志记录来看,Angular 在后退/前进时似乎并未实际确认片段,因此滚动并未被触发。

我决定订阅 URL 并在找到片段时手动滚动:

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();
      }
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

在这种方法中,我使用document.getElementId查找元素来滚动到视图中。因此,在这种方法中,URLfragment也是元素id。如果您想避免使用id's 而是通过 CSS 类或其他方式查找元素,则可以轻松修改此值。

最后,我将主应用程序模块中的设置更改回有关滚动等的默认设置。这种手动方法不需要非默认设置。

现在,我可以访问不同的锚点并在历史记录中后退/前进时看到滚动。希望它能帮助别人!

编辑:

为了在多个组件中重用此代码片段,我将其重构为自己的服务。该服务有一个方法,我可以从ngOnInit任何我想要锚点滚动的页面/组件调用该方法。

这是一个示例服务:

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

@Injectable({
  providedIn: 'any'
})
export class AnchorScrollService {

  constructor(private router: Router) { }

  listen(): Subscription {
    return 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();
        }
      }
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:最新的 Chrome 存在一个锚点滚动错误,我在初始导航中看到了这个错误。随后的导航/历史记录可以正常工作,并且在 Firefox 中一切都很完美。值得注意的是,如果您在 Chrome 上遇到挫折……您并不孤单!