Reputation: 163
I am trying to scroll to an anchor after navigating by routerlink using fragments.
** Component 1 **
<a routerLink="/training/{{ currentTrainingId }}" fragment="{{currentDomainId}}">
This link should bring the user to component 2. I hoped to achieve anchor scrolling by giving the element an id and then automatically adding #id in the URL using fragments.
** Component 2 **
<div *ngIf="all data has been loaded">
....
<domain-overview *ngFor="let domain of domains" [id]="domain.id"></domain-overview>
</div>
The generated URL does seem to be right.
http://localhost:4200/training/28#40
However, the anchor scrolling does not happen. I think it has something to do with asynchronously loading data. The domains have not loaded yet when anchor scrolling is executed..
I have created a static div and then the anchor scrolling works.
Does anyone have any idea how to deal with async data and anchor scrolling?
Do not rely on the automatic anchor scrolling, but instead program your own scroll function. Based on @Vinaayakh his answers I got the following working solution.
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
this.route.fragment.subscribe((fragment: string) => {
this.fragment = fragment;
});
Later, after loading all data in the complete section of the subscription, I call the scroll function.
setTimeout(() => {
this.scroll(this.fragment);
}, 250);
Upvotes: 7
Views: 8376
Reputation: 140
Update to include ActivatedRoute.snapshot (property) you can use without subscribing to the route fragment:
constructor(private route: ActivatedRoute){
this.fragment = this.route.snapshot.fragment
}
Then in your ngOnInit:
if(!!this.fragment){
this.scroll(this.fragment)
}
You can throw the if statement inside a setTimeout if needed, but this simplifies the code while not needing the unsubscribe in ngOnDestroy.
Upvotes: 2
Reputation: 522
Try adding this function
scroll(id){
const elmnt = document.getElementById(id);
elmnt.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
and add the function to HTML
<domain-overview *ngFor="let domain of domains" (click)="scroll(id)" [id]="domain.id"></domain-overview>
Upvotes: 6