Skip to content

Instantly share code, notes, and snippets.

@natebeaty
Created March 25, 2015 16:08
Show Gist options
  • Save natebeaty/1384423d4ee6a778a503 to your computer and use it in GitHub Desktop.
Save natebeaty/1384423d4ee6a778a503 to your computer and use it in GitHub Desktop.
// SCE - Firebelly 2015
// good design for good reason for good namespace
var SCE = (function($) {
var screen_width = 0,
is_desktop = false,
page_cache = [],
$content,
$backnav,
$body,
$document,
$nav,
History = window.History,
rootUrl = History.getRootUrl();
function _init() {
// set screen size vars
_resize();
// init state
State = History.getState();
$document = $(document);
$body = $('body');
$content = $('#main-content');
$nav = $('.site-nav');
// fit them vids!
$content.fitVids();
// init behavior for various sections
_initSearch();
_initNav();
_initAjaxLinks();
_initPeople();
_initGrantees();
_initMenuToggle();
_initSliders();
_initFeatureGrid();
_addEmptyFeatures();
_initFeatureGridNav();
_initProgramShowcase();
_initFaq();
_initMasonry();
// initial nav update based on URL
_updateNav();
// Esc handlers
$(document).keyup(function(e) {
if (e.keyCode == 27) {
_hideSearch();
_hideFeatured();
}
});
}
function _scrollBody(element, duration, delay) {
if ($('#wpadminbar').length) {
wpOffset = $('#wpadminbar').height();
} else {
wpOffset = 0;
}
element.velocity("scroll", {
duration: duration,
delay: delay,
offset: -wpOffset
}, "easeOutSine");
}
function _initSearch() {
$('.search-toggle, .internal-search-toggle').on('click', function (e) {
e.preventDefault();
if (!$('.search-wrap').hasClass('active')) {
$('.search-wrap').addClass('active');
$('.search-form input').focus();
} else _hideSearch();
});
$body.on('click', '.search-container', function (e) {
if (!$(e.target).is('.search-field')) {
_hideSearch();
}
});
}
function _hideSearch() {
$('.search-wrap').removeClass('active');
}
// Ajaxify all internal links in content area
function _initAjaxLinks() {
$content.find('a:internal:not(.no-ajaxy)').each(function() {
var href = $(this).attr('href');
if (!href.match(/\.(jpg|png|gif|pdf)$/)) {
$(this).click(function(e) {
e.preventDefault();
History.pushState(null, '', href);
});
}
});
}
function _updateTitle() {
var title = $content.find('.content:first').data('post-title');
if (title === '' || title === 'Main')
title = 'SCE';
else title = title + ' | SCE';
// this bit also borrowed from Ajaxify
document.title = title;
try {
document.getElementsByTagName('title')[0].innerHTML = document.title.replace('<','&lt;').replace('>','&gt;').replace(' & ',' &amp; ');
}
catch ( Exception ) { }
}
// handles main nav
function _initNav() {
$backnav = $('<a href="#" class="back-nav"><svg class="icon icon-arrow-left" role="img"><use xlink:href="#icon-arrow-left"></use></svg> <span>Back</span></a>').insertBefore('.site-nav');
$nav.find('>ul>li>a, li.dropdown>a').add('.branding a, a.back-nav').click(function(e) {
e.preventDefault();
var href = $(this).attr('href');
var title = $(this).text().trim();
if (title === '' || title === 'Main')
title = 'SCE';
else title = title + ' | SCE';
History.pushState(null, title, href);
});
// insert svgs
$nav.find('li.dropdown>a').append('<svg class="icon icon-arrow-tr" role="img"><use xlink:href="#icon-arrow-tr"></use></svg>');
$nav.find('li:not(.dropdown)>a').addClass('no-ajaxy').append('<svg class="icon icon-arrow-down" role="img"><use xlink:href="#icon-arrow-down"></use></svg>');
$(window).bind('statechange',function(){
var State = History.getState(),
url = State.url,
relative_url = url.replace(rootUrl,''),
parent_li;
if (relative_url === '') {
// homepage?
$nav.find('li').removeClass('active');
_updateNav();
} else if (relative_url.match(/^news/)) {
// blog post?
parent_li = $nav.find('li.menu-what-were-learning').addClass('active');
$nav.find('li').not(parent_li).removeClass('active');
_updateNav();
} else {
var nav_link = $nav.find('a[href="' + url + '"]');
if (nav_link) {
parent_li = nav_link.closest('li.dropdown').addClass('active');
$nav.find('li').not(parent_li).removeClass('active');
_updateNav();
}
}
if (!page_cache[encodeURIComponent(url)]) {
$.post(
url,
function(res) {
page_cache[encodeURIComponent(url)] = res;
SCE.updateContent();
}
);
} else {
_updateContent();
}
});
// add titles for subnavs
$nav.find('.dropdown').each(function() {
var title = $(this).find('a:first').text();
$(this).find('ul:first li:first').append('<h2>'+title+'</h2>');
});
// Final child pages scroll down
$nav.find('li.dropdown li>a').click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
var section = $('[data-url="' + url + '"]');
if (section.length)
_scrollBody(section, 250, 0);
});
}
function _updateContent() {
var State = History.getState();
var new_content = page_cache[encodeURIComponent(State.url)];
$content.removeClass('fadeInRight').addClass('fadeOutRight');
setTimeout(function() {
$content.html(new_content);
// pull in body class from data attribute
$body.attr('class', $content.find('.content:first').data('body-class'));
$content.removeClass('fadeOutRight').addClass('fadeInRight');
_updateTitle();
_initAjaxLinks();
_initSliders();
_initFaq();
_initMasonry();
_initFeatureGridNav();
_filterGrantees();
_addEmptyFeatures();
// clear out search
$('.search-field').val('');
// scroll to top
_scrollBody($body, 250, 0);
}, 150);
}
function _updateNav() {
// check if there's an active dropdown
var active_dropdown = $nav.find('.dropdown.active:last');
if (active_dropdown.length) {
var subnav = active_dropdown.find('ul:first').addClass('active');
$nav.find('.dropdown ul').not(subnav).removeClass('active');
// all parent ul's get .sub-active to push them over
active_dropdown.parents('ul').addClass('sub-active');
var parent_li = active_dropdown.parents('.dropdown:first');
if (parent_li.length) {
var link = parent_li.find('a:first');
$backnav.attr('href',link.attr('href')).addClass('active').find('span').text(link.text());
} else {
$backnav.attr('href','/').addClass('active').find('span').text('Main');
}
} else {
$nav.find('ul').removeClass('sub-active');
$backnav.removeClass('active');
}
}
function _initPeople() {
// Clicking on people makes them active
$content.on('click', 'ul.people>li', function(e) {
$('ul.people>li').not(this).removeClass('active');
$(this).toggleClass('active');
});
}
function _initGrantees() {
_filterGrantees();
$document.on('change', '.grantee-filters select', _filterGrantees);
}
function _filterGrantees() {
if (!$('.grantees').length) return false;
// Dropdown year + sector filters for grantees
var year = $('.grantee-filters select.year').val();
var sector = $('.grantee-filters select.sector').val();
$('.grantees li').velocity(
{ opacity: 0 },
{
duration: 250,
display: 'none'
}
);
var grantees = $('.grantees li');
if (year) {
grantees = grantees.filter('[data-year="' + year + '"]');
}
if (sector) {
grantees = grantees.filter('[data-sector="' + sector + '"]');
}
if (grantees.length) {
$('.grantees li.error').remove();
grantees.velocity(
{ opacity: 1 },
{
duration: 250,
display: 'block'
}
);
} else {
setTimeout(function() {
$('<li class="feature-item flex-item one-third shown error">No Grantees Found.</li>').appendTo('.grantees').hide().fadeIn();
}, 250);
}
}
function _initMenuToggle(){
$('.menu-toggle').on('click', function (e) {
e.preventDefault();
$('.right-side').toggleClass('menu-active');
$('.menu-toggle-wrap').toggleClass('menu-open');
$('#sidebar').toggleClass('active');
});
}
function _initSliders(){
$('.slider').slick({
slide: '.slide-item',
autoplay: $('.home.page').length>0,
autoplaySpeed: 8000,
speed: 800,
appendArrows: $('.slide-wrap-inner'),
prevArrow: '<svg class="slick-prev icon icon-arrow-left" role="img"><use xlink:href="#icon-arrow-left"></use></svg>',
nextArrow: '<svg class="slick-next icon icon-arrow-right" role="img"><use xlink:href="#icon-arrow-right"></use></svg>'
});
$('.home-slider .slick-prev').remove();
}
function _initFeatureGridNav(){
if ($('.feature-grid.expandable').length) {
if (!$('.feature-nav').length) {
$("<nav class='feature-nav'> \
<a href='#' class='feature-close'>Close</a> \
<ul> \
<li><a class='feature-next' href='#'>Next <span class='feature-type'>Initiative</span> <svg class='icon icon-arrow-right' role='img'><use xlink:href='#icon-arrow-right'></use></svg></a></li> \
<li><a class='feature-prev' href='#'>Prev <span class='feature-type'>Initiative</span> <svg class='icon icon-arrow-left' role='img'><use xlink:href='#icon-arrow-left'></use></svg></a></li> \
</ul> \
</nav>").insertBefore('.feature-grid.expandable');
}
// set Next ___ text
var feature_nav_title = $('.feature-grid.expandable').data('feature-nav-title');
$('.feature-nav .feature-type').text(feature_nav_title);
}
// duplicate titles + subtitles for slide out
$content.find('.feature-grid.expandable .feature-item:not(".initialized")').each(function() {
var title = $(this).find('h5').clone();
title.find('svg').remove();
$(this).addClass('initialized').find('.info .-left').prepend(title);
});
}
function _initFeatureGrid(){
var featureItem = '.feature-grid.expandable .feature-item:not(.active, .-empty)',
featureClose = '.feature-close',
$active = $('.feature-grid').find('.feature-item.active');
// Activate the selected feature item
$content.on('click', featureItem, function (e) {
e.preventDefault();
// close any open features
$('.feature-item.active').removeClass('active');
$(this).addClass('active');
$(this).prepend("<a href='#' class='feature-close'>Close</a>");
var $active = $(this);
$body.addClass('feature-active');
_scrollBody($(this), 500, 0);
});
// Feature item navigation
$content.on('click', '.feature-next', function (e) {
e.preventDefault();
var $active = $('.feature-grid').find('.feature-item.active');
// find next or first feature-item
var $next = ($active.next(':not(.-empty)').length > 0) ? $active.next(':not(.-empty)') : $('.feature-item:first');
$next.trigger('click');
});
$content.on('click', '.feature-prev', function (e) {
e.preventDefault();
var $active = $('.feature-grid').find('.feature-item.active');
// find prev or last feature-item
var $prev = ($active.prev().length > 0) ? $active.prev() : $('.feature-item:not(.-empty):last');
$prev.trigger('click');
});
// Grantee featured-grid items just open up links
$content.on('click', '.feature-grid.external-links .feature-item', function(e) {
e.preventDefault();
var href = $(this).find('a:first').attr('href');
if (href)
window.open(href, '_blank');
});
// close it all!
$content.on('click', featureClose, function (e) {
e.preventDefault();
_hideFeatured();
});
}
function _addEmptyFeatures() {
if($('.feature-grid').length ){
var items = $('.feature-item').length,
remainders = (Math.ceil(items / 3) * 3) - items;
for(var i = 0; i < remainders; i++) {
$('.feature-grid').append('<li class="feature-item flex-item one-third -empty empty' + (i + 1) + '"></li>');
}
}
}
function _hideFeatured() {
$('.feature-item.active .feature-close').remove();
$('.feature-item.active').removeClass('active');
$body.removeClass('feature-active');
}
function _initProgramShowcase(){
var speed = 5000,
t = setTimeout(runFader,speed);
function runFader() {
$('.fader').each(function () {
var $active = $(this).find('.active');
var $next = ($active.next().length > 0) ? $active.next() : $(this).find('li:first');
$active.removeClass('active');
$next.addClass('active');
});
speed = 5000;
t = setTimeout(runFader, speed);
}
}
function _initFaq(){
$document.on('click', '.faq-nav a', function(e) {
e.preventDefault();
var $this = $(this);
if ($this.closest('li').hasClass('active')) return false;
var targetFaq = $this.attr('href');
$('.faq-nav li.active, .faq-answer.active').removeClass('active');
setTimeout(function() {
$this.closest('li').addClass('active');
$(targetFaq + '.faq-answer').addClass('active');
// History.replaceState(null, null, $this.attr('href'));
}, 250);
});
// check if we're linking to #faq2 (not currently used)
if (location.hash !== '' && location.hash.match(/faq/)) {
$('.faq-nav li a[href="'+location.hash+'"]').closest('li').addClass('active');
$('.faq-answer'+location.hash).addClass('active');
// scroll to FAQ section
_scrollBody($('.faq'), 250, 0);
} else if ($('.faq-nav li.active').length === 0) {
// make first FAQ active if none selected
$('.faq-nav li:first, .faq-answer:first').addClass('active');
}
}
function _initMasonry(){
var $container = $('.masonry');
$container.masonry({
itemSelector: 'article',
transitionDuration: '.3s'
});
}
// track ajax pages in Analytics
function _trackPage() {
if (typeof ga != 'undefined') ga('send', 'pageview', document.location.href);
}
// track events in Analytics
function _trackEvent(category, action) {
if (typeof ga != 'undefined') ga('send', 'event', category, action);
}
// called in quick succession as window is resized
function _resize() {
screenWidth = document.documentElement.clientWidth;
is_desktop = screenWidth > 768;
}
// public functions
return {
init: _init,
resize: _resize,
updateContent: _updateContent,
scrollBody: function(section, duration, delay) {
_scrollBody(section, duration, delay);
}
};
})(jQuery);
// fire up the mothership
jQuery(document).ready(SCE.init);
// zig-zag the mothership
jQuery(window).resize(SCE.resize);
(function($){
// Internal Helper (from Ajaxify)
$.expr[':'].internal = function(obj, index, meta, stack){
// Prepare
var
$this = $(obj),
url = $this.attr('href')||'',
isInternalLink,
rootUrl = History.getRootUrl();
// Check link
isInternalLink = url.substring(0,rootUrl.length) === rootUrl || url.indexOf(':') === -1;
// Ignore or Keep
return isInternalLink;
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment