Angular 7.x.x easiest way to scroll to a fragment?

Exitl0l picture Exitl0l · Feb 7, 2019 · Viewed 9.4k times · Source

In the past two days i've been diggin through the internetz about scrolling a fragment into view with angular.

Let's say we have a static webpage with a bunch of id-s that act as fragments. And has a side nav-bar to navigate through the fragments with links.

I've tried Router anchorScroll simply adding this to the module is doing nothing for me. It just gives you the fragment in the URL but no scrolling.

I've tried viewportScroller. The main issue with this is it's not working for the first time (eg.: you are redirected to this static page with to a desired fragment, but the scrolling is not happening, if you've been on this same page and repeat the process, it works, if you click on the link at the side nav-bar that has the same url as you are visiting: ([foo]/[bar]#[fragment]) it's not working either since no navigation has changed.

extra options used for router:

const routerOptions: ExtraOptions = {
  useHash: false,
  anchorScrolling: 'enabled',
  scrollPositionRestoration: 'enabled',
  onSameUrlNavigation: 'reload'
};

ps.: useHash: true makes no change what so ever.

viewportScroller inside ngOnInit:

this.viewportScroller.setOffset([0, 64]);
this.viewportScroller.setHistoryScrollRestoration('auto');

this.router.events.pipe(filter(element => element instanceof Scroll)).subscribe((element: any) => {
  console.log(element)
  this.viewportScroller.scrollToAnchor(element.anchor);
});

What is the easiest way to scroll to a fragment WITHOUT!!! using this:

ngOnInit() {
  this.route.fragment.subscribe((fragment: string) => { 
    if (fragment && document.getElementById(fragment) != null) {
      document.getElementById(fragment).scrollIntoView({ behavior: "smooth" });
    }
  });
}

b/c with that it works every time but it's not TS, as we use TS in our company's projects.

Help me out please

Answer

Tom Schreck picture Tom Schreck · Apr 4, 2019

I had this same issue. Check out this solution by Ben Nadel. The solution is for Angular 7.X. You can configure RouterModule to handle anchor scrolling, even works with multiple clicks on the anchor with fragment. Here's the code you need:

 @NgModule({
  imports: [RouterModule.forRoot(routes,
            {
              anchorScrolling: 'enabled',
              onSameUrlNavigation: 'reload',
              scrollPositionRestoration: 'enabled'
            })],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Hope this helps.