Skip to content

Instantly share code, notes, and snippets.

@CSilivestru
Last active December 11, 2015 10:48
Show Gist options
  • Save CSilivestru/4588831 to your computer and use it in GitHub Desktop.
Save CSilivestru/4588831 to your computer and use it in GitHub Desktop.
Integrating Junior into your mobile web app
Jr.Navigator = {
backButtonFlag: true, //Junior manages the backButton state for us.
...
...
renderView: function(mainEl, view) {
var animation, newEl;
animation = this.history.length > 0 ? this.history[this.history.length -1].animation : null;
//In the renderView function, I've added some support here to trigger a back event if it happened. Notice thw two events.
//A generic back event and a view specific event. This gives us some flexibility in case we want app-wide back detection.
//These evetns fire BEFORE the animation begins and the view paramter is the view you're moving back to.
if (this.backButtonFlag === true) {
Backbone.Events.trigger("back");
try {
Backbone.Events.trigger("back-" + Jr.viewIdentifier, view);
Jr.viewIdentifier = view.viewIdentifier;
//If we get an error here, we're on initial app load (first page of the app)
} catch (e) {
Backbone.Events.trigger("back-" + this.viewIdentifier, view);
}
}
if (animation) {
newEl = $('<div></div>');
this.resetContent(newEl, view);
this.normalRenderView(newEl, view);
this.animate(mainEl, newEl, animation.type, animation.direction);
return this.afterAnimation();
} else {
this.resetContent(mainEl, view);
return this.normalRenderView(mainEl, view);
}
},
...
...
doAnimation: function(fromEl, toEl, type, direction) {
var after, next;
$('#app-container').prepend(toEl);
toEl.addClass('animate-to-view').addClass(direction).addClass('initial');
$('#app-container').addClass('animate');
$('#app-container').addClass(direction);
next = function() {
return toEl.removeClass('initial');
};
setTimeout(next, 1);
after = function(isBackNavigation) { //I added a parameter here so that the after animation code is aware of the back button press
//Context is lost when we hit this function which is why we need to do this.
fromEl.remove();
toEl.attr('id', 'app-main');
toEl.removeClass('animate-to-view').removeClass(direction);
//Here we trigger two events. A generic back animation complete and a view specific back animation complete
if (isBackNavigation) {
Backbone.Events.trigger("backAnimationComplete");
if (Jr.viewIdentifier)
Backbone.Events.trigger("backAnimationComplete-" + Jr.viewIdentifier);
}
else { //If it's not a back button hit, we'll trigger the regular animation complete events
Backbone.Events.trigger("animationComplete");
Jr.viewIdentifier = this.viewIdentifier;
Backbone.Events.trigger("animationComplete-" + Jr.viewIdentifier); }
return $('#app-container').removeClass('animate').removeClass(direction);
};
var isBackNavigation = this.backButtonFlag;
return setTimeout(function() {after(isBackNavigation);}, 400);
}
Jr.Navigator = {
viewIdentifier: "", //I give an initial value of the view we're on a blank value. Just don't want it to start off being null
backButtonFlag: true,
...
...
navigate: function(url, opts) {
viewIdentifier = url; //My view identifier is the matched route used in Junior
this.history.push(opts);
this.backButtonFlag = false;
return Backbone.history.navigate(url, opts);
},
...
...
renderView: function(mainEl, view) {
var animation, newEl;
animation = this.history.length > 0 ? this.history[this.history.length -1].animation : null;
if (this.backButtonFlag === true) {
Backbone.Events.trigger("back");
try {
//We trigger the generic event name + it's identifier. Now we can hook into a per-view event!
//Simple but effective
Backbone.Events.trigger("back-" + Jr.viewIdentifier, view);
Jr.viewIdentifier = view.viewIdentifier;
} catch (e) {
Backbone.Events.trigger("back-" + this.viewIdentifier, view);
}
//In order to get rid of zombie Junior views, I extended Jr to include an AppView variable.
//Instead of call view.render(), we'll call AppView.showView(view, this) from your router
Jr.AppView = {
currentView: null,
previousView: null,
showView: function(view, router) {
if (this.currentView)
this.previousView = this.currentView;
this.currentView = view;
router.renderView(this.currentView);
if (this.previousView){
var that = this;
setTimeout(function() {
that.previousView.close();
}, 400);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment