Difference between revisions of "Template:Tongji Software/js/main js"

(Created page with "/** * main.js * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Copyright 2015, Codrops * http://w...")
 
 
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);
+

Latest revision as of 08:13, 5 October 2019

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'); }); } }); });