Created
February 8, 2014 10:04
-
-
Save farleyta/8881336 to your computer and use it in GitHub Desktop.
JavaScript feature-based execution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Modified http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/ | |
// And http://viget.com/extend/javascript-execution-patterns-for-non-web-apps | |
var NAMESPACE = { | |
// All pages | |
common: { | |
init: function() { | |
// Some universal variables | |
var breakpoint = 768; | |
// Initialize header style based on window width | |
if ( $(window).width() >= breakpoint ) { | |
$('body').attr('data-features', 'desktopHeader'); | |
$('.nav-main').addClass('desktopHeader'); | |
} else { | |
$('body').attr('data-features', 'mobileHeader'); | |
$('.nav-main').addClass('mobileHeader'); | |
} | |
// Behavior on window resizing = swap between menu types | |
$(window).resize(function(){ | |
if ( $(window).width() >= breakpoint && $('.nav-main').hasClass('mobileHeader')) { | |
$('body').attr('data-features', 'desktopHeader'); | |
$('.nav-main').toggleClass('desktopHeader mobileHeader'); | |
NAMESPACE.features.desktopHeader(); | |
} | |
if ( $(window).width() < breakpoint && $('.nav-main').hasClass('desktopHeader')) { | |
$('body').attr('data-features', 'mobileHeader'); | |
$('.nav-main').toggleClass('desktopHeader mobileHeader'); | |
NAMESPACE.features.mobileHeader(); | |
} | |
}); | |
// Add the double arrow icon font to READ MORE text | |
$('a.read_more').append(' <i class="icon-angle-double-right"></i>'); | |
} | |
}, | |
// Home Page only | |
home: { | |
init: function() { | |
} | |
}, | |
// Contact Page only | |
contact: { | |
init: function() { | |
} | |
}, | |
// Feature-specific functions | |
features: { | |
mobileHeader: function() { | |
// Add Menu toggle button | |
$('.nav-main').prepend('<ul class="menu-link show-only-for-mobile"><li><span class="menu-button"><i class="icon-menu-1"></i>Menu<i class="menu-toggle icon-down-open-1"></i></span></li></ul>'); | |
// Hide menu by default | |
$('.menu-primary-navigation').hide(); | |
// When Menu toggle is clicked show/hide main menu | |
$('.nav-main').on('click','.menu-link',function(){ | |
// Alternate between the up and down arrow | |
$(this).find('.menu-toggle').toggleClass('icon-down-open-1 icon-up-open-1'); | |
$(this).siblings('.menu-primary-navigation').slideToggle('fast'); | |
}); | |
// Hide all submenus with dropdowns as well | |
$('.menu-primary-navigation .dropdown-menu').hide(); | |
// Add dropdown arrow to any menu items that have a submenu | |
$('.menu-primary-navigation .dropdown > a').after('<span class="menu-button"><i class="dropdown-menu-toggle icon-plus"></i></span>'); | |
// When dropdown arrow is clicked, show/hide submenu | |
$('.menu-primary-navigation .dropdown .menu-button').on('click', function(){ | |
$(this).next('.dropdown-menu').slideToggle('fast', function() { | |
// and alternate between up arrow and down arrow | |
$(this).prev('.menu-button').children('.dropdown-menu-toggle').toggleClass('icon-plus icon-minus'); | |
}); | |
// Also, hide any other previously open submenus | |
$(this).parent().siblings().find('.dropdown-menu:visible').slideToggle('fast', function() { | |
// and alternate between up arrow and down arrow | |
$(this).prev('.menu-button').children('.dropdown-menu-toggle').toggleClass('icon-plus icon-minus'); | |
}); | |
}); | |
// Move the search form from the header to within the nav menu | |
$('#menu-primary-navigation').append('<li class="search-form-list-item"></li>'); | |
$('.header-top .search-form').detach().appendTo('.search-form-list-item'); | |
}, | |
desktopHeader: function() { | |
// Remove the mobile menu if it exists (ie - we're resizing) | |
if ( $('.nav-main').children('.menu-link').length ) { | |
NAMESPACE.features.destroyMobileHeader(); | |
} | |
}, | |
// And a function to reset any DOM manipulations done by the mobile header | |
destroyMobileHeader: function() { | |
// Remove Menu toggle button | |
$('.menu-link').remove(); | |
// Unhide full menu and all submenus, and remove toggle buttons | |
$('.menu-primary-navigation').show().find('.dropdown-menu').show().siblings('.menu-button').remove(); | |
// Also remove all .on('click') events | |
$('.nav-main').off('click'); | |
$('.menu-primary-navigation .dropdown .menu-button').off('click'); | |
// Detach the search form and move it back to its original location in the DOM | |
$('.menu-primary-navigation .search-form').detach().insertAfter('.logo'); | |
$('.search-form-list-item').remove(); | |
} | |
} | |
}; | |
var UTIL = { | |
fire: function(func, funcname, args) { | |
var namespace = NAMESPACE; | |
funcname = (funcname === undefined) ? 'init' : funcname; | |
if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function'){ | |
namespace[func][funcname](args); | |
} | |
}, | |
loadEvents: function() { | |
UTIL.fire('common'); | |
$.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) { | |
UTIL.fire(classnm); | |
}); | |
// Custom added function to execute any functions named in "data-features" on body | |
if ( $('body').data('features') ) { | |
$.each($('body').data('features').replace(/-/g, '_').split(/\s+/), function(i,featurenm){ | |
UTIL.fire('features', featurenm); | |
}); | |
} | |
UTIL.fire('common', 'finalize'); | |
} | |
}; | |
$(document).ready(UTIL.loadEvents); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment