Reputation: 509
I am having an issue with viewportScroller named in the title.
In my project I need to redirect from a nested url to a simple static terms&conditions site (which has a navigation sidebar to navigate within the site to each anchor).
Which works fine, but it's not scrolling to the desired fragment at first. If you visit the said terms&conditions site and do the whole workflow again(go to the nested url-> click on a link that's redirecting you to the terms site) then it takes you to the wanted fragment. And it's not letting me scroll to the same fragment twice with the navbar.
the link that redirects you :
<a routerLink="/terms-and-conditions"
fragment="practice-customer-key-obligations">Terms and Conditions</a>
terms component:
import { Component, OnInit, AfterViewChecked } from '@angular/core';
import { Router, Scroll } from '@angular/router';
import { ViewportScroller } from '@angular/common';
import { filter } from 'rxjs/operators';
@Component({
selector: 'app-terms-and-conditions',
templateUrl: './terms-and-conditions.component.html',
styleUrls: ['./terms-and-conditions.component.scss']
})
export class TermsAndConditionsComponent implements OnInit, AfterViewChecked {
constructor(private router: Router, private viewportScroller: ViewportScroller) {
}
ngOnInit() {
}
ngAfterViewChecked() {
this.viewportScroller.setOffset([0, 64]);
this.viewportScroller.setHistoryScrollRestoration('auto');
this.router.events.pipe(filter(element => element instanceof Scroll)).subscribe((element: any) => {
this.viewportScroller.scrollToAnchor(element.anchor);
});
}
}
terms routing module:
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule, Routes, ExtraOptions } from '@angular/router';
import { BasicLayout } from '../layouts';
import { TermsAndConditionsComponent } from './terms-and-conditions/terms-and-conditions.component';
const routes: Routes = [
{
path: '', component: BasicLayout,
children: [
{ path: 'terms-and-conditions', component: TermsAndConditionsComponent }
]
}
];
const routerOptions: ExtraOptions = {
useHash: false,
anchorScrolling: 'enabled',
scrollPositionRestoration: 'enabled'
};
@NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forRoot(routes, routerOptions)
],
exports: [
RouterModule
]
})
export class TermsRoutingModule { }
What am I missing here? If there's an easier way what is it?
PS.: I am forbidden to use JS DOM manipulation like this:
this.route.fragment.subscribe((fragment: string): void => {
if (fragment && document.getElementById(fragment) !== null) {
document.getElementById(fragment).scrollIntoView({ behavior: "smooth" });
}
Upvotes: 4
Views: 14690
Reputation: 79
The documentation is confusing, but you do not need to use fragments (or router or extra options) to use viewportscroller, it's completely separate. You should be able to assign an ID to the element you want to scroll to, and just use this.viewportscroller.scrollToAnchor(elementID)
on the click event. I used this recently and it worked in the ngOnInit lifecycle hook.
If you need to use the router for actual navigation to a part of a page, try looking at this article for how to implement router links by Ben Nadel
Upvotes: 0