|
|
| Line 1: |
Line 1: |
| − | /**
| + | jQuery(document).ready(function($){ |
| − | * main.js
| + | //if you change this breakpoint in the style.css file (or _layout.scss if you use SASS), don't forget to update this value as well |
| − | * http://www.codrops.com
| + | var MQL = 1170; |
| − | *
| + | |
| − | * Licensed under the MIT license.
| + | |
| − | * http://www.opensource.org/licenses/mit-license.php
| + | |
| − | *
| + | |
| − | * Copyright 2015, Codrops
| + | |
| − | * http://www.codrops.com
| + | |
| − | */
| + | |
| − | ;(function(window) { | + | |
| | | | |
| − | 'use strict'; | + | //primary navigation slide-in effect |
| − | | + | if($(window).width() > MQL) { |
| − | var support = { transitions: Modernizr.csstransitions },
| + | var headerHeight = $('.cd-header').height(); |
| − | // transition end event name
| + | $(window).on('scroll', |
| − | transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' },
| + | { |
| − | transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ],
| + | previousTop: 0 |
| − | onEndTransition = function( el, callback ) {
| + | }, |
| − | var onEndCallbackFn = function( ev ) {
| + | function () { |
| − | if( support.transitions ) {
| + | var currentTop = $(window).scrollTop(); |
| − | if( ev.target != this ) return;
| + | //check if user is scrolling up |
| − | this.removeEventListener( transEndEventName, onEndCallbackFn );
| + | if (currentTop < this.previousTop ) { |
| − | }
| + | //if scrolling up... |
| − | if( callback && typeof callback === 'function' ) { callback.call(this); }
| + | if (currentTop > 0 && $('.cd-header').hasClass('is-fixed')) { |
| − | };
| + | $('.cd-header').addClass('is-visible'); |
| − | if( support.transitions ) {
| + | } else { |
| − | el.addEventListener( transEndEventName, onEndCallbackFn );
| + | $('.cd-header').removeClass('is-visible is-fixed'); |
| − | }
| + | } |
| − | else {
| + | } else { |
| − | onEndCallbackFn();
| + | //if scrolling down... |
| − | }
| + | $('.cd-header').removeClass('is-visible'); |
| − | }, | + | if( currentTop > headerHeight && !$('.cd-header').hasClass('is-fixed')) $('.cd-header').addClass('is-fixed'); |
| − | // the pages wrapper
| + | } |
| − | stack = document.querySelector('.pages-stack'),
| + | this.previousTop = currentTop; |
| − | // the page elements
| + | |
| − | pages = [].slice.call(stack.children),
| + | |
| − | // total number of page elements | + | |
| − | pagesTotal = pages.length,
| + | |
| − | // index of current page
| + | |
| − | current = 0,
| + | |
| − | // menu button
| + | |
| − | menuCtrl = document.querySelector('button.menu-button'),
| + | |
| − | // the navigation wrapper
| + | |
| − | nav = document.querySelector('.pages-nav'),
| + | |
| − | // the menu nav items | + | |
| − | navItems = [].slice.call(nav.querySelectorAll('.link--page')),
| + | |
| − | // check if menu is open
| + | |
| − | isMenuOpen = false;
| + | |
| − | | + | |
| − | function init() {
| + | |
| − | buildStack();
| + | |
| − | initEvents();
| + | |
| − | }
| + | |
| − | | + | |
| − | function buildStack() {
| + | |
| − | var stackPagesIdxs = getStackPagesIdxs();
| + | |
| − | | + | |
| − | // set z-index, opacity, initial transforms to pages and add class page--inactive to all except the current one
| + | |
| − | for(var i = 0; i < pagesTotal; ++i) {
| + | |
| − | var page = pages[i],
| + | |
| − | posIdx = stackPagesIdxs.indexOf(i);
| + | |
| − | | + | |
| − | if( current !== i ) {
| + | |
| − | classie.add(page, 'page--inactive');
| + | |
| − | | + | |
| − | if( posIdx !== -1 ) {
| + | |
| − | // visible pages in the stack
| + | |
| − | page.style.WebkitTransform = 'translate3d(0,100%,0)';
| + | |
| − | page.style.transform = 'translate3d(0,100%,0)';
| + | |
| − | }
| + | |
| − | else {
| + | |
| − | // invisible pages in the stack
| + | |
| − | page.style.WebkitTransform = 'translate3d(0,75%,-300px)';
| + | |
| − | page.style.transform = 'translate3d(0,75%,-300px)';
| + | |
| − | }
| + | |
| − | }
| + | |
| − | else {
| + | |
| − | classie.remove(page, 'page--inactive');
| + | |
| − | }
| + | |
| − | | + | |
| − | page.style.zIndex = i < current ? parseInt(current - i) : parseInt(pagesTotal + current - i);
| + | |
| − |
| + | |
| − | if( posIdx !== -1 ) {
| + | |
| − | page.style.opacity = parseFloat(1 - 0.1 * posIdx);
| + | |
| − | }
| + | |
| − | else {
| + | |
| − | page.style.opacity = 0;
| + | |
| − | }
| + | |
| − | }
| + | |
| − | }
| + | |
| − | | + | |
| − | // event binding
| + | |
| − | function initEvents() {
| + | |
| − | // menu button click
| + | |
| − | menuCtrl.addEventListener('click', toggleMenu);
| + | |
| − | | + | |
| − | // navigation menu clicks
| + | |
| − | navItems.forEach(function(item) {
| + | |
| − | // which page to open?
| + | |
| − | var pageid = item.getAttribute('href').slice(1);
| + | |
| − | item.addEventListener('click', function(ev) {
| + | |
| − | ev.preventDefault();
| + | |
| − | openPage(pageid);
| + | |
| − | });
| + | |
| | }); | | }); |
| − |
| |
| − | // clicking on a page when the menu is open triggers the menu to close again and open the clicked page
| |
| − | pages.forEach(function(page) {
| |
| − | var pageid = page.getAttribute('id');
| |
| − | page.addEventListener('click', function(ev) {
| |
| − | if( isMenuOpen ) {
| |
| − | ev.preventDefault();
| |
| − | openPage(pageid);
| |
| − | }
| |
| − | });
| |
| − | });
| |
| − |
| |
| − | // keyboard navigation events
| |
| − | document.addEventListener( 'keydown', function( ev ) {
| |
| − | if( !isMenuOpen ) return;
| |
| − | var keyCode = ev.keyCode || ev.which;
| |
| − | if( keyCode === 27 ) {
| |
| − | closeMenu();
| |
| − | }
| |
| − | } );
| |
| | } | | } |
| | | | |
| − | // toggle menu fn | + | //open/close primary navigation |
| − | function toggleMenu() {
| + | $('.cd-primary-nav-trigger').on('click', function(){ |
| − | if( isMenuOpen ) {
| + | $('.cd-menu-icon').toggleClass('is-clicked'); |
| − | closeMenu();
| + | $('.cd-header').toggleClass('menu-is-open'); |
| − | }
| + | |
| − | else {
| + | |
| − | openMenu();
| + | |
| − | isMenuOpen = true;
| + | |
| − | }
| + | |
| − | }
| + | |
| − | | + | |
| − | // opens the menu
| + | |
| − | function openMenu() { | + | |
| − | // toggle the menu button
| + | |
| − | classie.add(menuCtrl, 'menu-button--open')
| + | |
| − | // stack gets the class "pages-stack--open" to add the transitions
| + | |
| − | classie.add(stack, 'pages-stack--open');
| + | |
| − | // reveal the menu
| + | |
| − | classie.add(nav, 'pages-nav--open');
| + | |
| − | | + | |
| − | // now set the page transforms
| + | |
| − | var stackPagesIdxs = getStackPagesIdxs();
| + | |
| − | for(var i = 0, len = stackPagesIdxs.length; i < len; ++i) { | + | |
| − | var page = pages[stackPagesIdxs[i]];
| + | |
| − | page.style.WebkitTransform = 'translate3d(0, 75%, ' + parseInt(-1 * 200 - 50*i) + 'px)'; // -200px, -230px, -260px
| + | |
| − | page.style.transform = 'translate3d(0, 75%, ' + parseInt(-1 * 200 - 50*i) + 'px)';
| + | |
| − | } | + | |
| − | }
| + | |
| − | | + | |
| − | // closes the menu
| + | |
| − | function closeMenu() {
| + | |
| − | // same as opening the current page again
| + | |
| − | openPage();
| + | |
| − | }
| + | |
| − | | + | |
| − | // opens a page
| + | |
| − | function openPage(id) {
| + | |
| − | var futurePage = id ? document.getElementById(id) : pages[current],
| + | |
| − | futureCurrent = pages.indexOf(futurePage),
| + | |
| − | stackPagesIdxs = getStackPagesIdxs(futureCurrent);
| + | |
| − | | + | |
| − | // set transforms for the new current page
| + | |
| − | futurePage.style.WebkitTransform = 'translate3d(0, 0, 0)';
| + | |
| − | futurePage.style.transform = 'translate3d(0, 0, 0)';
| + | |
| − | futurePage.style.opacity = 1;
| + | |
| − | | + | |
| − | // set transforms for the other items in the stack
| + | |
| − | for(var i = 0, len = stackPagesIdxs.length; i < len; ++i) {
| + | |
| − | var page = pages[stackPagesIdxs[i]];
| + | |
| − | page.style.WebkitTransform = 'translate3d(0,100%,0)';
| + | |
| − | page.style.transform = 'translate3d(0,100%,0)';
| + | |
| − | }
| + | |
| − | | + | |
| − | // set current
| + | |
| − | if( id ) {
| + | |
| − | current = futureCurrent;
| + | |
| − | }
| + | |
| | | | |
| − | // close menu.. | + | //in firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden |
| − | classie.remove(menuCtrl, 'menu-button--open'); | + | if( $('.cd-primary-nav').hasClass('is-visible') ) { |
| − | classie.remove(nav, 'pages-nav--open');
| + | $('.cd-primary-nav').removeClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){ |
| − | onEndTransition(futurePage, function() {
| + | $('body').removeClass('overflow-hidden'); |
| − | classie.remove(stack, 'pages-stack--open');
| + | }); |
| − | // reorganize stack | + | } else { |
| − | buildStack();
| + | $('.cd-primary-nav').addClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){ |
| − | isMenuOpen = false;
| + | $('body').addClass('overflow-hidden'); |
| − | }); | + | }); |
| − | }
| + | |
| − | | + | |
| − | // gets the current stack pages indexes. If any of them is the excludePage then this one is not part of the returned array
| + | |
| − | function getStackPagesIdxs(excludePageIdx) {
| + | |
| − | var nextStackPageIdx = current + 1 < pagesTotal ? current + 1 : 0,
| + | |
| − | nextStackPageIdx_2 = current + 2 < pagesTotal ? current + 2 : 1,
| + | |
| − | idxs = [],
| + | |
| − | | + | |
| − | excludeIdx = excludePageIdx || -1;
| + | |
| − | | + | |
| − | if( excludePageIdx != current ) {
| + | |
| − | idxs.push(current);
| + | |
| | } | | } |
| − | if( excludePageIdx != nextStackPageIdx ) {
| + | }); |
| − | idxs.push(nextStackPageIdx);
| + | }); |
| − | }
| + | |
| − | if( excludePageIdx != nextStackPageIdx_2 ) {
| + | |
| − | idxs.push(nextStackPageIdx_2);
| + | |
| − | }
| + | |
| − | | + | |
| − | return idxs;
| + | |
| − | } | + | |
| − | | + | |
| − | init();
| + | |
| − | | + | |
| − | })(window); | + | |
jQuery(document).ready(function($){
//if you change this breakpoint in the style.css file (or _layout.scss if you use SASS), don't forget to update this value as well
var MQL = 1170;
//primary navigation slide-in effect
if($(window).width() > MQL) {
var headerHeight = $('.cd-header').height();
$(window).on('scroll',
{
previousTop: 0
},
function () {
var currentTop = $(window).scrollTop();
//check if user is scrolling up
if (currentTop < this.previousTop ) {
//if scrolling up...
if (currentTop > 0 && $('.cd-header').hasClass('is-fixed')) {
$('.cd-header').addClass('is-visible');
} else {
$('.cd-header').removeClass('is-visible is-fixed');
}
} else {
//if scrolling down...
$('.cd-header').removeClass('is-visible');
if( currentTop > headerHeight && !$('.cd-header').hasClass('is-fixed')) $('.cd-header').addClass('is-fixed');
}
this.previousTop = currentTop;
});
}
//open/close primary navigation
$('.cd-primary-nav-trigger').on('click', function(){
$('.cd-menu-icon').toggleClass('is-clicked');
$('.cd-header').toggleClass('menu-is-open');
//in firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
if( $('.cd-primary-nav').hasClass('is-visible') ) {
$('.cd-primary-nav').removeClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
$('body').removeClass('overflow-hidden');
});
} else {
$('.cd-primary-nav').addClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
$('body').addClass('overflow-hidden');
});
}
});
});