What I am trying to do is to create an anchor link. This link will navigate to a specific scroll point in my page. I have Angular version 5.
Html:
<mat-list>
<mat-list-item><a [routerLink]="['/']"> Intro </a></mat-list-item>
<mat-list-item><a [routerLink]="['/']" fragment="mobile"> Mobile </a></mat-list-item>
...
</mat-list>
In home.componets.ts:
export class HomeGrComponent implements OnInit {
private fragment: string;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.fragment.subscribe(fragment => { this.fragment = fragment; });
}
ngAfterViewInit(): void {
try {
setTimeout(()=> {
document.querySelector('#' + this.fragment).scrollIntoView();
}, 1000);
} catch (e) { }
}
}
I took this code from this question but it doesn't work. Url is changed to
http://localhost:4200/#mobile
but it didn't scroll to my point. Also in console there is an error:
Cannot read property 'scrollIntoView' of null
What can be possible goes wrong? If you need some additional information please ask me to reply. Also it could be great the scroll navigates smoothly (optional).
You can use the following Code:
import { Component, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { filter } from 'rxjs/operators';
import { Subscription } from 'rxjs';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnDestroy {
private sub: Subscription;
constructor(activeRoute: ActivatedRoute) {
this.sub = activeRoute.fragment.pipe(filter(f => !!f)).subscribe(f => document.getElementById(f).scrollIntoView());
}
public ngOnDestroy(): void {
if(this.sub) this.sub.unsubscribe();
}
}
Working example and Code behind
The reason why it's not working is that ngAfterViewInit
is being called before the Observable
is resolved, and therefore this.fragment
is null, so no element is found
ngOnInit() {
this.route.fragment.subscribe(fragment => {
this.fragment = fragment;
});
}
ngAfterViewInit(): void {
let interval = setInterval(()=> {
let elem = document.getElementById(this.fragment);
if(elem) {
elem.scrollIntoView();
clearInterval(interval);
}
}, 1000);
}
Another option is to use setTimout() . So you don't need clearInterval(). You can also access the fragment with the help of the ActivatedRoute
constructor(private route: ActivatedRoute) {}
ngAfterViewInit(): void {
setTimeout(() => document.querySelector(this.route.snapshot.fragment).scrollIntoView(), 1000);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.