Article summary
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!
Great summary here of a really common problem.
We also needed to handle scrolling to the top of the page on clicking pagination when the route itself doesn’t necessarily change, but the query parameters do. We have a component that simply handles the `click()` event and yields.
Code is available here: https://github.com/code-corps/code-corps-ember/blob/develop/app/components/scroll-top.js
And some example usage here: https://github.com/code-corps/code-corps-ember/blob/develop/app/templates/components/pager-control.hbs#L4