Skip to content

Turbolinks Page Transitions

Kevin Pheasey edited this page Dec 18, 2018 · 19 revisions

Turbolinks is a great way to increase site performance since assets aren't loaded everytime and only the body of the page is refreshed. Another bonus is being able to transition between pages. Using the following Transitions class, we can hook into the page:fetch and page:change TurboLinks callbacks in order to provide a fade out/in transition between GET requests.

We are using CSS3 animations provided by - https://daneden.github.io/animate.css/

# app/assets/javascripts/base.js.coffee
class App.Base

  constructor: ->
    App.transitions = new Element.Transitions
    return this
# app/assets/javascripts/elements/transitions.js.coffee
class Element.Transitions

  constructor: ->
    # Turbolinks < 5
    $(document).on 'page:fetch.transition', @out
    $(document).on 'page:change.transition', @in
    $(document).on 'page:before-unload.transition', @remove
    $(document).on 'page:restore.transition', @remove

    # Turbolinks >= 5
    $(document).on 'turbolinks:request-start.transition', @out
    $(document).on 'turbolinks:load.transition', @in
    $(document).on 'turbolinks:before-cache.transition', @remove

    return this


  out: =>
    $('#main-container .page-content').addClass('animated fadeOut')
    App.transitionLoader = setTimeout( ->
      $('#ajax-loader').fadeIn('slow')
    , 1500
    )
    return


  in: =>
    $('#main-container .page-content').addClass('animated fadeIn')
    setTimeout( @remove, 1000 )
    window.clearTimeout(App.transitionLoader) if App.transitionLoader?
    return


  remove: =>
    $('#main-container .page-content').removeClass('animated fadeOut fadeIn')
    $('#ajax-loader').hide()
    window.clearTimeout(App.transitionLoader) if App.transitionLoader?
    return

The above example will fade out/in the main-content and also includes a 1.5s timeout that shows a loader element. If you have a page that takes a while to load, showing a loading animation will let the user know that something is happening.

Animate.css comes with tons of animations that could be used, such as sliding, wiping, bouncing, etc. Additionally, you don't need to fade the entire <body> element, instead you could target a specific element, such as the main content.

Clone this wiki locally