diff --git a/README.md b/README.md index aa837547..a0111075 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # ember-router-scroll -[![Build Status](https://travis-ci.org/dollarshaveclub/ember-router-scroll.svg?branch=master)](https://travis-ci.org/dollarshaveclub/ember-router-scroll) - -[![Greenkeeper badge](https://badges.greenkeeper.io/dollarshaveclub/ember-router-scroll.svg)](https://greenkeeper.io/) +[![Build Status](https://travis-ci.org/dollarshaveclub/ember-router-scroll.svg?branch=master)](https://travis-ci.org/dollarshaveclub/ember-router-scroll) [![Greenkeeper badge](https://badges.greenkeeper.io/dollarshaveclub/ember-router-scroll.svg)](https://greenkeeper.io/) > Scroll to page top on transition, like a non-SPA website. An alternative scroll behavior for Ember applications. @@ -16,63 +14,38 @@ ember install ember-router-scroll Like all good ember addons, this behavior was considered for core implementation. Good news, people like the idea. For now, the feature will live under the flag `ember-unique-location-history-state` until it's finally released in Ember 2.13. You can follow along for yourself [here](https://github.com/emberjs/ember.js/pull/14011/) and read up on the [RFC](https://github.com/emberjs/rfcs/pull/186#issuecomment-271416805) if you'd like as well. -## Demo +## A working example See [demo](https://dollarshaveclub.github.io/router-scroll-demo/) and [repo](https://github.com/dollarshaveclub/router-scroll-demo) made by [Jon Chua](https://github.com/Chuabacca/). -## Real Life Usage +## A visual demo ### Before ![before-scroll](https://cloud.githubusercontent.com/assets/4430436/17122972/0a1fe454-5295-11e6-937f-f1f5beab9d6b.gif) -Notice that the in the full purple page, the user is sent to the **middle** of the page + +Notice that the in the full purple page, the user is sent to the **middle** of the page. ### After ![after-scroll](https://cloud.githubusercontent.com/assets/4430436/17122970/07c1a3a0-5295-11e6-977f-37eb955d95b1.gif) -Notice that the in the full purple page, the user is sent to the **top** of the page -## Why Use it? +Notice that the in the full purple page, the user is sent to the **top** of the page. -Ember expects an application to be rendered with nested views. The default behavior is for the scroll position to be preserved on every transition. +## Why Use it? -However not all Ember applications use nested views. For these applications, a user would expect to see the top of the page on most transitions. +Ember expects an application to be rendered with nested views. The default behavior is for the scroll position to be preserved on every transition. However, not all Ember applications use nested views. For these applications, a user would expect to see the top of the page on most transitions. In addition to scrolling to the top of the page on most transitions, a user would expect the scroll position to be preserved when using the back or forward browser buttons. -**Ember-router-scroll** makes your single page application feel more like a regular website. - -## How it works - -#### Definitions - -For the purposes of this section, here are some definitions: - -`previous route`: the route you are leaving - -`next route`: the route you are going to next - -`popStateEvent`: the event triggered by clicking the back or forward button in the browser. See more [here at mdn](https://developer.mozilla.org/en-US/docs/Web/Events/popstate). - -#### Details: - -**Ember-router-scroll** is a mixin that adds behavior to the `willTransition` and `didTransition` hooks in the router. - -When `willTransition` is triggered, the scroll position is stored in a map with the **previous route's** ID from the HistoryLocation API as the key with the scroll position as the value. - -`scrollMap[previous_route] = 1234` - -On `didTransition`, it first checks to see if the route transition was triggered by a `popStateEvent`. If so, go to the scroll position defined by the `scrollMap`. Otherwise, scroll to the top of the page. - - **With one exception: if the queryParam `preserveScrollPosition` is set to `true`, it maintains the scroll position of the previous route. See below for further information on this queryParam.** +**ember-router-scroll** makes your single page application feel more like a regular website. ## Usage -### Step 1: Install Ember Router Scroll +1. Install addon ```bash ember install ember-router-scroll ``` -### Step 2: Import ember-router-scroll - +2. Import ember-router-scroll In your app/router.js file, import the mixin: @@ -83,10 +56,10 @@ import RouterScroll from 'ember-router-scroll'; And add RouterScroll as an extension to your Router object: ```javascript -const Router = Ember.Router.extend(RouterScroll, {} +const Router = Ember.Router.extend(RouterScroll, {}); ``` -### Step 3: Update your app's locationType +3. Update your app's `locationType` Edit `config/environment.js` and change `locationType`. Also add `historySupportMiddleware: true,` to get live-reload working in nested routes. (See [Issue #21](https://github.com/dollarshaveclub/ember-router-scroll/issues/21)) @@ -98,16 +71,15 @@ historySupportMiddleware: true, This location type inherits from Ember's `HistoryLocation`. -### Step 4: Tests +4. Tests In your router and controller tests, add `'service:router-scroll',` it as a dependency in the `needs: []` block: ```js //{your-app}}/tests/unit/routes/{{your-route}}.js needs:[ 'service:router-scroll' ], ``` -### Step 5: Profit -## Preserve Scroll Position +## Issues with nested routes ### Before: ![before-preserve](https://cloud.githubusercontent.com/assets/4430436/17122971/0a1e34ce-5295-11e6-8d30-9f687dd69dbb.gif) @@ -119,11 +91,11 @@ Notice the unwanted scroll to top in this case. Adding a query parameter or controller property fixes this issue. -#### preserveScrollPosition with queryParams +### preserveScrollPosition with queryParams In certain cases, you might want to have certain routes preserve scroll position when coming from a specific location. For example, inside your application, there is a way to get to a route where the user expects scroll position to be preserved (such as a tab section). -1. Step 1. +1. Add query param in controller Add `preserveScrollPosition` as a queryParam in the controller for the route that needs to preserve the scroll position. @@ -139,7 +111,7 @@ export default Ember.Controller.extend({ }); ``` -1. Step 2. +2. Pass in query param Next, in the place where a transition is triggered, pass in `preserveScrollPosition=true`. For example @@ -147,11 +119,12 @@ Next, in the place where a transition is triggered, pass in `preserveScrollPosit {{link-to "About Tab" 'tab.about' (query-params preserveScrollPosition=true) }} ``` -#### preserveScrollPosition with a controller property +### preserveScrollPosition wiith a controller property In other cases, you may have certain routes that always preserve scroll position, or routes where the controller can decide when to preserve scroll position. For instance, you may have some nested routes that have true nested UI where preserving scroll position is expected. Or you want a particular route to start off with the default scroll-to-top behavior but then preserve scroll position when query params change in reponse to user interaction. Using a conroller property also allows the use of preserveScrollPosition without adding this to the query params. -1. Step 1. + +1. Add query param to controller Add `preserveScrollPosition` as a controller property for the route that needs to preserve the scroll position. In this example we have `preserveScrollPosition` initially set to false so that we get our normal scroll-to-top behavior when the route loads. Later on, when an action triggers a change to the `filter` query param, we also set `preserveScrollPosition` to true so that this user interaction does not trigger the scroll-to-top behavior. @@ -171,13 +144,13 @@ export default Ember.Controller.extend({ this.set('preserveScrollPosition', true); this.set('filter', filter); } - } + } }); ``` -1. Step 2. +2. Reset preserveScrollPosition if necessary -If your controller is changing the preserveScrollPosition property, you'll probably need to reset preserveScrollPosition back to the default behavior whenever the controller is reset. This is not necceary on routes where `preserveScrollPosition` is always set to true. +If your controller is changing the preserveScrollPosition property, you'll probably need to reset `preserveScrollPosition` back to the default behavior whenever the controller is reset. This is not necceary on routes where `preserveScrollPosition` is always set to true. ```javascript import Ember from 'ember'; @@ -189,30 +162,8 @@ export default Ember.Route.extend({ }); ``` - - -## Development Instructions - -* `git clone` this repository -* `npm install` -* `bower install` - -## Running - -* `ember server` -* Visit your app at http://localhost:4200. - ## Running Tests * `npm test` (Runs `ember try:testall` to test your addon against multiple Ember versions) * `ember test` * `ember test --server` - -## Building - -* `ember build` - -For more information on using ember-cli, visit [http://ember-cli.com/](http://ember-cli.com/). diff --git a/package.json b/package.json index 547d3a19..dcbf04db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-router-scroll", - "version": "0.1.1", + "version": "0.2.0", "description": "Scroll to top with preserved browser history scroll position", "directories": { "doc": "doc",