Skip to content

Instantly share code, notes, and snippets.

@tjFogarty
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjFogarty/3e586a6ba7c8dda882dd to your computer and use it in GitHub Desktop.
Save tjFogarty/3e586a6ba7c8dda882dd to your computer and use it in GitHub Desktop.
Handle mobile navigation
/*global module, $, _, matchMedia*/
'use strict';
/**
* Navigation
* Disclaimer: This is built with jQuery.mmenu in mind, and so some of the selectors and calls accommodate this
* Shouldn't be too hard to swap this out for a different menu solution
*
* @param config
* @constructor
*/
var Navigation = function(config) {
this.selector = config.selector;
this.activeClass = config.activeClass || 'is-visible';
this.hiddenClass = config.hiddenClass || 'is-hidden';
this.breakpoint = config.breakpoint || '767px';
this.el = $(config.selector);
this.mobileEl = null; // won't be set until it's generated
// Kick things off
this.generateMobile();
};
/**
* Generate mobile version
* @function generateMobile
*/
Navigation.prototype.generateMobile = function() {
var _self = this;
// Generate mobile nav
this.el.mmenu({}, {
clone: true
});
this.mobileEl = $(this.selector + '.mm-menu');
this.toggleMobile();
// This is probably done arse-ways - trying to keep context bound to 'this', not window event
$(window).on('resize', _.debounce(function() {
_self.toggleMobile.apply(_self);
}, 300));
};
/**
* Check if mobile based on passed in breakpoint
* @function isMobile
*/
Navigation.prototype.isMobile = function() {
// If Modernizr.mq isn't set, just assign an empty function
return matchMedia('(max-width: ' + this.breakpoint + ')').matches;
};
/**
* Show mobile, hide desktop
* @function showMobile
*/
Navigation.prototype.showMobile = function() {
this.mobileEl.addClass(this.activeClass).removeClass(this.hiddenClass);
this.el.removeClass(this.activeClass).addClass(this.hiddenClass);
};
/**
* Show desktop, hide mobile
* @function hideMobile
*/
Navigation.prototype.hideMobile = function() {
this.mobileEl.removeClass(this.activeClass).addClass(this.hiddenClass);
this.el.addClass(this.activeClass).removeClass(this.hiddenClass);
};
/**
* Based on matchMedia we can show/hide the mobile menu
* jQuery performance hit on .hide() or .show() can be avoid by using classes
* @function toggleMobile
*/
Navigation.prototype.toggleMobile = function() {
// 1. Hide desktop, show mobile
// 2. Hide mobile, show desktop
this.isMobile() ? this.showMobile() : this.hideMobile();
};
var mainNav = new Navigation({
selector: '.nav--main'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment