DEV Community

Cover image for Tree Ways to Scroll to an Element using Angular
Fernando Raposo da Camara Silva
Fernando Raposo da Camara Silva

Posted on • Edited on

Tree Ways to Scroll to an Element using Angular

Recently I was implementing in Angular a requirement that demanded the following:

"After pressing a button, if some specific data is returned, present a warning with a link saying that the specific data exists. After clicking on that link, scroll down to the grid containing the data".

First, I tried the simplest solution, which was the use of DOM commands like Element.scrollIntoView(), or
document.getElementById("<yourTarget>").scrollIntoView({
behavior: "smooth",
block: "start",
inline: "nearest"
});

(Remeber to add id="<yourtarget" where you want to scroll)
It worked on development, and it was quite easy, but after deploying to production environment I noticed that the scroll was not working!

So, I tried another way, using Angular's ViewportScroller.
In order to do that, you have to inject ViewportScroller at Component's constructor, like constructor(private scroller: ViewportScroller) and just call this.scroller.scrollToAnchor("<yourTarget>");. Again, no big deal, and again it was NOT WORKING on production environment.

The third way to do it, is to use Router to provide navigation to the anchor I wanted. Similarly to the last option, inject Router to constructor, like constructor(private router: Router), and use the command:
this.router.navigate([], { fragment: "<yourTarget>" });
Finally it DID WORK on production environment! I don't know for sure why the previous methods failed, I read some sources that says Angular Material blocks scrolling, but I'm not sure.
In order to present the different options there's a Stackblitz as an example.
There you can click on tree buttons, each one using a different method to scroll down to some anchor.


Hope it helps someone :)

Top comments (12)

Collapse
 
geraldbustos profile image
Gerald Bustos

Gracias, buenas ideas!

Collapse
 
3vil4aron profile image
3vil4aron

You also could just do this in the template itself: StackBlitz

Collapse
 
p_leppard profile image
Paul Leppard

Helped me, thanks. I'm looking at building elearning which has sections hidden until you click the continue button, then it scrolls down to the next section. Needed a setTimeout for it to scroll to previously hidden divs but works very nicely. Thanks.

Collapse
 
ferfox1981 profile image
Fernando Raposo da Camara Silva

you're welcome!

Collapse
 
sinsunsan profile image
Sébastien LUCAS

Hello,

In my case the other way to scroll (document and scroller way) were sometimes not working because triggering at a moment in the loading process where the element was not on screen. It is in my case a table.

So probably we need to trigger them once we are sure the html element we want to scroll to in in the DOM.

Collapse
 
mirab20251348 profile image
Mira-B

Use router is not correct solution IMHO. Did you try to click to button "scroll to blue Div" and than scroll up a click the button again? Nothing will happen because URL has been already changed.

Collapse
 
madankumar7 profile image
MadanKumar7

I am trying this now in Angular 12 version, you are gonna need to add the following code in app-routing, for the fragment route to work now. "onSameUrlNavigation: 'reload'" option will resolve the issue.

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

imports: [RouterModule.forRoot(routes, routerOptions)],

Collapse
 
danny2768 profile image
Daniel Cobos

You just saved me a ton of time.

Collapse
 
ferfox1981 profile image
Fernando Raposo da Camara Silva

Everyone has a top choice. There's no 100% right or wrong.

Collapse
 
kaellandrade profile image
Micael Andrade

Thanks!

Collapse
 
pookdeveloper profile image
pookdeveloper

with non-static html it wouldn't work

Collapse
 
femio profile image
Femi Olowofoyeku

I've done the third one for the blue box and there's no error, but it's just not working.