AngularJS ui-router, scroll to next step on state change

All we need is an easy explanation of the problem, so here it is.

I’m using UI-router in my app and I’d like to so a simple “scrollTo” to an anchor when the URL/state changes. I don’t want to load the next step from a template, or load a new controller. I’d just like several divs to be on the page already and scroll up and down between them. A simplified view of the HTML would be this.

    <div id="step1">
        <button ng-click="moveToStep2()">Continue</button>
    <div id="step2">
        <button ng-click="moveToStep3()">Continue</button>
    <div id="step3">
        Step 3 content

So, when you enter the page the URL would be

When you click the first button I’d like my controller code to change the URL to and scroll down to the “step2” div.

Ideally, when the user hits the back button it would revert to the first URL and scroll back up to step 1.

Anybody know how to do this?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

First. You need to define the state.

.state('step1', {
    url: '/step-1'

Add onEnter controller (so you can $inject things).

.state('step1', {
    url: '/step-1',
    onEnter: function () {}

Animate (or simply scroll) to element

$('html, body').animate({
    scrollTop: $("#step1").offset().top
}, 2000);

Here the example

Method 2


You can do something like this:

$stateProvider.state("step1", {
  template: 'template.html',
  controller: ...,
  onEnter: function(){

Method 3

You can listen to $locationChangeSuccess, e.g.

$rootScope.$on('$locationChangeSuccess', scrollBasedOnLocationChangeEvent);

Basic example:$urlRouter

Method 4

If the divs are already on the current page, just hard code the href to teh current

<div id="step1">
<a href="wizard.html#/wizard/start#step1" rel="nofollow noreferrer noopener">Continue to step 1</a>
<div id="step2">
<a href="wizard.html#/wizard/start#step2" rel="nofollow noreferrer noopener">Continue step 2</a>
<div id="step3">
    Step 3 content

<a name="#step2">STEP 2</a>

<a name="#step1">STEP 1</a>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply