1 Comment

Ember.js – Scroll to the Top on Every Page Load

Resetting the scroll position to the top when a page loads is very common in modern websites. By default, Ember actually retains the current scroll position as you navigate between pages. This is a little strange because new pages you navigate to may load halfway down the page.

Create a Mixin

To work around this, you’ll want to create a mixin, which allows the same group of code to be applied to many different classes.

For this example, I’ll use the following file name for the mixin: reset-scroll-position.js. I chose to tie into the activate method. According to the Ember docs, “[activate] is executed when the router enters the route. It is not executed when the model for the route changes.”

reset-scroll-position.js:


import Ember from 'ember';

export default Ember.Mixin.create({
  activate: function() {
    this._super();
    window.scrollTo(0,0);
  }
});

This mixin will be applied to a route, so you’ll want to choose the routes where you’ll apply it. In my case, I wanted to apply it to all routes. I ended up creating a base route that all routes in my app extend.

base.js:


import Ember from 'ember';
import ResetScrollPositionMixin from 'my-app/mixins/reset-scroll-position';

export default Ember.Route.extend(ResetScrollPositionMixin, {});

some-other-route.js:


import BaseRoute from 'my-app/routes/base';

export default BaseRoute.extend({
  ...
});

An Option with More Flexibility

In case you are looking for more flexibility, such as having a different scroll position for each route, there’s a nice open-source library called ember-cli-reset-scroll. Here is their usage example:


import Ember from 'ember';
import ResetScrollMixin from 'ember-cli-reset-scroll';

export default Ember.Route.extend(ResetScrollMixin, {

  // Scrolls to top
  resetScroll: undefined

  // Scroll to a specific position (in px)
  resetScroll: 20

  // Scroll to a specific position based on the route name (in px)
  resetScroll: {
    'books.index': 30,
    'authors.*': 210
  }

});

I hope this helps!