An opinionated way to implement page transitions in a Backbone.js application. Part of a larger post found here: http://mikefowler.me/2013/11/18/page-transitions-in-backbone/
A Pen by Mike Fowler on CodePen.
<footer class="footer" role="contentinfo"> | |
<p>This demo is part of a post by Mike Fowler titled <a href="http://mikefowler.me/2013/11/18/page-transitions-in-backbone" target="page-transitions-in-backbone">“Page Transitions in Backbone”</a>.</p> | |
</footer> | |
<script type="text/template" name="home"> | |
<h1>Home</h1> | |
<p><a href="#/activity">Activity →</a></p> | |
</script> | |
<script type="text/template" name="activity"> | |
<h1>Activity</h1> | |
<p><a href="#/">← Home</a></p> | |
</script> |
An opinionated way to implement page transitions in a Backbone.js application. Part of a larger post found here: http://mikefowler.me/2013/11/18/page-transitions-in-backbone/
A Pen by Mike Fowler on CodePen.
(function () { | |
window.app = { | |
Views: {}, | |
Extensions: {}, | |
Router: null, | |
init: function () { | |
this.instance = new app.Views.App(); | |
Backbone.history.start(); | |
} | |
}; | |
$(function() { | |
window.app.init(); | |
}); | |
app.Router = Backbone.Router.extend({ | |
routes: { | |
'activity': 'activity', | |
'': 'home' | |
}, | |
home: function () { | |
var view = new app.Views.Home(); | |
app.instance.goto(view); | |
}, | |
activity: function () { | |
var view = new app.Views.Activity(); | |
app.instance.goto(view); | |
} | |
}); | |
app.Extensions.View = Backbone.View.extend({ | |
initialize: function () { | |
this.router = new app.Router(); | |
}, | |
render: function(options) { | |
options = options || {}; | |
if (options.page === true) { | |
this.$el.addClass('page'); | |
} | |
return this; | |
}, | |
transitionIn: function (callback) { | |
var view = this, | |
delay | |
var transitionIn = function () { | |
view.$el.addClass('is-visible'); | |
view.$el.one('transitionend', function () { | |
if (_.isFunction(callback)) { | |
callback(); | |
} | |
}) | |
}; | |
_.delay(transitionIn, 20); | |
}, | |
transitionOut: function (callback) { | |
var view = this; | |
view.$el.removeClass('is-visible'); | |
view.$el.one('transitionend', function () { | |
if (_.isFunction(callback)) { | |
callback(); | |
}; | |
}); | |
} | |
}); | |
app.Views.App = app.Extensions.View.extend({ | |
el: 'body', | |
goto: function (view) { | |
var previous = this.currentPage || null; | |
var next = view; | |
if (previous) { | |
previous.transitionOut(function () { | |
previous.remove(); | |
}); | |
} | |
next.render({ page: true }); | |
this.$el.append( next.$el ); | |
next.transitionIn(); | |
this.currentPage = next; | |
} | |
}); | |
app.Views.Home = app.Extensions.View.extend({ | |
className: 'home', | |
render: function () { | |
var template = _.template($('script[name=home]').html()); | |
this.$el.html(template()); | |
return app.Extensions.View.prototype.render.apply(this, arguments); | |
} | |
}); | |
app.Views.Activity = app.Extensions.View.extend({ | |
className: 'activity', | |
render: function () { | |
var template = _.template($('script[name=activity]').html()); | |
this.$el.html(template()); | |
return app.Extensions.View.prototype.render.apply(this, arguments); | |
} | |
}); | |
}()); |
* { | |
box-sizing: border-box; | |
} | |
body { | |
margin: 0; | |
padding: 0; | |
font: 150% Futura-Medium, Futura, sans-serif; | |
color: #333; | |
} | |
h1 { | |
font-weight: normal; | |
} | |
a { | |
color: #F2994B; | |
} | |
.page { | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
padding: 1em; | |
text-align: center; | |
transition: transform 0.5s ease; | |
transform: translate3d(100%, 0, 0); | |
} | |
.page a { | |
color: white; | |
} | |
.page.is-visible { | |
transform: translate3d(0, 0, 0); | |
} | |
.home { | |
color: white; | |
background: #F2CF66; | |
} | |
.activity { | |
color: white; | |
background: #F2994B; | |
} | |
.footer { | |
position: fixed; | |
bottom: 0; | |
left: 0; | |
width: 100%; | |
padding: 10px; | |
background: white; | |
z-index: 10; | |
} |