app/assets/javascripts/foundation/foundation.topbar.js
/*jslint unparam: true, browser: true, indent: 2 */
;(function ($, window, document, undefined) {
'use strict';
Foundation.libs.topbar = {
name : 'topbar',
version: '4.3.2',
settings : {
index : 0,
stickyClass : 'sticky',
custom_back_text: true,
back_text: 'Back',
is_hover: true,
mobile_show_parent_link: false,
scrolltop : true, // jump to top when sticky nav menu toggle is clicked
init : false
},
init : function (section, method, options) {
Foundation.inherit(this, 'data_options addCustomRule');
var self = this;
if (typeof method === 'object') {
$.extend(true, this.settings, method);
} else if (typeof options !== 'undefined') {
$.extend(true, this.settings, options);
}
if (typeof method !== 'string') {
$('.top-bar, [data-topbar]').each(function () {
$.extend(true, self.settings, self.data_options($(this)));
self.settings.$w = $(window);
self.settings.$topbar = $(this);
self.settings.$section = self.settings.$topbar.find('section');
self.settings.$titlebar = self.settings.$topbar.children('ul').first();
self.settings.$topbar.data('index', 0);
var topbarContainer = self.settings.$topbar.parent();
if(topbarContainer.hasClass('fixed') || topbarContainer.hasClass(self.settings.stickyClass)) {
self.settings.$topbar.data('height', self.outerHeight(topbarContainer));
self.settings.$topbar.data('stickyoffset', topbarContainer.offset().top);
} else {
self.settings.$topbar.data('height', self.outerHeight(self.settings.$topbar));
}
var breakpoint = $("<div class='top-bar-js-breakpoint'/>").insertAfter(self.settings.$topbar);
self.settings.breakPoint = breakpoint.width();
breakpoint.remove();
self.assemble();
if (self.settings.is_hover) {
self.settings.$topbar.find('.has-dropdown').addClass('not-click');
}
// Pad body when sticky (scrolled) or fixed.
self.addCustomRule('.f-topbar-fixed { padding-top: ' + self.settings.$topbar.data('height') + 'px }');
if (self.settings.$topbar.parent().hasClass('fixed')) {
$('body').addClass('f-topbar-fixed');
}
});
if (!self.settings.init) {
this.events();
}
return this.settings.init;
} else {
// fire method
return this[method].call(this, options);
}
},
toggle: function() {
var self = this;
var topbar = $('.top-bar, [data-topbar]'),
section = topbar.find('section, .section');
if (self.breakpoint()) {
if (!self.rtl) {
section.css({left: '0%'});
section.find('>.name').css({left: '100%'});
} else {
section.css({right: '0%'});
section.find('>.name').css({right: '100%'});
}
section.find('li.moved').removeClass('moved');
topbar.data('index', 0);
topbar
.toggleClass('expanded')
.css('height', '');
}
if(self.settings.scrolltop)
{
if (!topbar.hasClass('expanded')) {
if (topbar.hasClass('fixed')) {
topbar.parent().addClass('fixed');
topbar.removeClass('fixed');
$('body').addClass('f-topbar-fixed');
}
} else if (topbar.parent().hasClass('fixed')) {
if (self.settings.scrolltop) {
topbar.parent().removeClass('fixed');
topbar.addClass('fixed');
$('body').removeClass('f-topbar-fixed');
window.scrollTo(0,0);
} else {
topbar.parent().removeClass('expanded');
}
}
} else {
if(topbar.parent().hasClass(self.settings.stickyClass)) {
topbar.parent().addClass('fixed');
}
if(topbar.parent().hasClass('fixed')) {
if (!topbar.hasClass('expanded')) {
topbar.removeClass('fixed');
topbar.parent().removeClass('expanded');
self.updateStickyPositioning();
} else {
topbar.addClass('fixed');
topbar.parent().addClass('expanded');
}
}
}
},
timer : null,
events : function () {
var self = this;
$(this.scope)
.off('.fndtn.topbar')
.on('click.fndtn.topbar', '.top-bar .toggle-topbar, [data-topbar] .toggle-topbar', function (e) {
e.preventDefault();
self.toggle();
})
.on('click.fndtn.topbar', '.top-bar li.has-dropdown', function (e) {
var li = $(this),
target = $(e.target),
topbar = li.closest('[data-topbar], .top-bar'),
is_hover = topbar.data('topbar');
if(target.data('revealId')) {
self.toggle();
return;
}
if (self.breakpoint()) return;
if (self.settings.is_hover && !Modernizr.touch) return;
e.stopImmediatePropagation();
if (target[0].nodeName === 'A' && target.parent().hasClass('has-dropdown')) {
e.preventDefault();
}
if (li.hasClass('hover')) {
li
.removeClass('hover')
.find('li')
.removeClass('hover');
li.parents('li.hover')
.removeClass('hover');
} else {
li.addClass('hover');
}
})
.on('click.fndtn.topbar', '.top-bar .has-dropdown>a, [data-topbar] .has-dropdown>a', function (e) {
if (self.breakpoint() && $(window).width() != self.settings.breakPoint) {
e.preventDefault();
var $this = $(this),
topbar = $this.closest('.top-bar, [data-topbar]'),
section = topbar.find('section, .section'),
dropdownHeight = $this.next('.dropdown').outerHeight(),
$selectedLi = $this.closest('li');
topbar.data('index', topbar.data('index') + 1);
$selectedLi.addClass('moved');
if (!self.rtl) {
section.css({left: -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({left: 100 * topbar.data('index') + '%'});
} else {
section.css({right: -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({right: 100 * topbar.data('index') + '%'});
}
topbar.css('height', self.outerHeight($this.siblings('ul'), true) + self.settings.$topbar.data('height'));
}
});
$(window).on('resize.fndtn.topbar', function () {
if (typeof self.settings.$topbar === 'undefined') { return; }
var stickyContainer = self.settings.$topbar.parent('.' + this.settings.stickyClass);
var stickyOffset;
if (!self.breakpoint()) {
var doToggle = self.settings.$topbar.hasClass('expanded');
$('.top-bar, [data-topbar]')
.css('height', '')
.removeClass('expanded')
.find('li')
.removeClass('hover');
if(doToggle) {
self.toggle();
}
}
if(stickyContainer.length > 0) {
if(stickyContainer.hasClass('fixed')) {
// Remove the fixed to allow for correct calculation of the offset.
stickyContainer.removeClass('fixed');
stickyOffset = stickyContainer.offset().top;
if($(document.body).hasClass('f-topbar-fixed')) {
stickyOffset -= self.settings.$topbar.data('height');
}
self.settings.$topbar.data('stickyoffset', stickyOffset);
stickyContainer.addClass('fixed');
} else {
stickyOffset = stickyContainer.offset().top;
self.settings.$topbar.data('stickyoffset', stickyOffset);
}
}
}.bind(this));
$('body').on('click.fndtn.topbar', function (e) {
var parent = $(e.target).closest('li').closest('li.hover');
if (parent.length > 0) {
return;
}
$('.top-bar li, [data-topbar] li').removeClass('hover');
});
// Go up a level on Click
$(this.scope).on('click.fndtn', '.top-bar .has-dropdown .back, [data-topbar] .has-dropdown .back', function (e) {
e.preventDefault();
var $this = $(this),
topbar = $this.closest('.top-bar, [data-topbar]'),
section = topbar.find('section, .section'),
$movedLi = $this.closest('li.moved'),
$previousLevelUl = $movedLi.parent();
topbar.data('index', topbar.data('index') - 1);
if (!self.rtl) {
section.css({left: -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({left: 100 * topbar.data('index') + '%'});
} else {
section.css({right: -(100 * topbar.data('index')) + '%'});
section.find('>.name').css({right: 100 * topbar.data('index') + '%'});
}
if (topbar.data('index') === 0) {
topbar.css('height', '');
} else {
topbar.css('height', self.outerHeight($previousLevelUl, true) + self.settings.$topbar.data('height'));
}
setTimeout(function () {
$movedLi.removeClass('moved');
}, 300);
});
},
breakpoint : function () {
return $(document).width() <= this.settings.breakPoint || $('html').hasClass('lt-ie9');
},
assemble : function () {
var self = this;
// Pull element out of the DOM for manipulation
this.settings.$section.detach();
this.settings.$section.find('.has-dropdown>a').each(function () {
var $link = $(this),
$dropdown = $link.siblings('.dropdown'),
url = $link.attr('href');
if (self.settings.mobile_show_parent_link && url && url.length > 1) {
var $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li><li><a class="parent-link js-generated" href="' + url + '">' + $link.text() +'</a></li>');
} else {
var $titleLi = $('<li class="title back js-generated"><h5><a href="#"></a></h5></li>');
}
// Copy link to subnav
if (self.settings.custom_back_text == true) {
$titleLi.find('h5>a').html(self.settings.back_text);
} else {
$titleLi.find('h5>a').html('« ' + $link.html());
}
$dropdown.prepend($titleLi);
});
// Put element back in the DOM
this.settings.$section.appendTo(this.settings.$topbar);
// check for sticky
this.sticky();
},
height : function (ul) {
var total = 0,
self = this;
ul.find('> li').each(function () { total += self.outerHeight($(this), true); });
return total;
},
sticky : function () {
var $window = $(window),
self = this;
$window.scroll(function() {
self.updateStickyPositioning();
});
},
updateStickyPositioning: function() {
var klass = '.' + this.settings.stickyClass;
var $window = $(window);
if ($(klass).length > 0) {
var distance = this.settings.$topbar.data('stickyoffset');
if (!$(klass).hasClass('expanded')) {
if ($window.scrollTop() > (distance)) {
if (!$(klass).hasClass('fixed')) {
$(klass).addClass('fixed');
$('body').addClass('f-topbar-fixed');
}
} else if ($window.scrollTop() <= distance) {
if ($(klass).hasClass('fixed')) {
$(klass).removeClass('fixed');
$('body').removeClass('f-topbar-fixed');
}
}
}
}
},
off : function () {
$(this.scope).off('.fndtn.topbar');
$(window).off('.fndtn.topbar');
},
reflow : function () {}
};
}(Foundation.zj, this, this.document));