Angular4 - Scrolling to anchor

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-30 11:20:49

I think it's more simple solution :

In your HTML :

<a [routerLink]="['/']" fragment="login"></a>

In your typescript :

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

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

Automatic Scrolling

Since Angular v6, there is the new anchorScrolling option for the RouterModule. You can set it in the module's import:

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

With this, Angular will automatically scroll to the element with the id of the given fragment.

⚠️ However, this does not work when the data is loaded asynchronously, see this Github issue. ⚠️


Manual Scrolling

Smooth scrolling is not yet possible via the RouterModule, but you can do it manually:

1) Get your target e.g. with ViewChild:

@ViewChild('pageInfo') pageInfo: ElementRef; 

2) Call scrollIntoView on the nativeElement:

const targetElement = this.pageInfo.nativeElement
targetElement.scrollIntoView({behavior: "smooth"})

With Angular 4 you can have some problem using anchor to the same page.

I solved using this way

ng2-page-scroll

install

npm install ng2-page-scroll --save

import in your app.module.ts

import {Ng2PageScrollModule} from 'ng2-page-scroll';

@NgModule({
    imports: [
        /* Other imports here */
        Ng2PageScrollModule
        ]
})
export class AppModule {
}

test it in your html component

<a pageScroll href="#test">Testing</a>
<div id="test">

AfterViewCheck() will be called every time the ChangeDetection is triggered, so it is a bad solution.

Use AfterViewInit() like

public ngAfterViewInit(): void {
  this.subscription = this.route.fragment
    .subscribe(fragment => {
        const targetElement = this.document.querySelector('#' + fragment);
        if (fragment && targetElement) {
            targetElement.scrollIntoView();
        } else {
            window.scrollTo(0, 0);
        }
    });
}
public ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

This is a more detailed example to add to Sarah Dubois' answer above.

Import router modules.

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

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

  router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {    
      if (event.url) {
        this.route.fragment.subscribe(fragment => this.fragment = fragment);
      }
    }
  });

}

ngAfterViewChecked(): void {

  try {
    if(this.fragment != null) {
     document.querySelector("a[name="+this.fragment+"]").scrollIntoView();
    }
  } catch (e) {
    //console.log(e, 'error');
  }

}

I like the use of querySelector which will give you a lot of options to which element you would like to scroll to. https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

This works with Angular 8 :)

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