|
@@ -1,38 +1,73 @@
|
|
|
/*************************************************
|
|
|
- * Hugo Academic: an academic theme for Hugo.
|
|
|
+ * Academic: the personal website framework for Hugo.
|
|
|
* https://github.com/gcushen/hugo-academic
|
|
|
**************************************************/
|
|
|
|
|
|
(function($){
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
- * Add smooth scrolling to all links inside the main navbar.
|
|
|
+ * Responsive scrolling for URL hashes.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- $('#navbar-main li.nav-item a').on('click', function(event){
|
|
|
+ // Dynamically get responsive navigation bar offset.
|
|
|
+ let $navbar = $('.navbar-header');
|
|
|
+ let navbar_offset = $navbar.innerHeight();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Responsive hash scrolling.
|
|
|
+ * Check for a URL hash as an anchor.
|
|
|
+ * If it exists on current page, scroll to it responsively.
|
|
|
+ * If `target` argument omitted (e.g. after event), assume it's the window's hash.
|
|
|
+ */
|
|
|
+ function scrollToAnchor(target) {
|
|
|
+ // If `target` is undefined or HashChangeEvent object, set it to window's hash.
|
|
|
+ target = (typeof target === 'undefined' || typeof target === 'object') ? window.location.hash : target;
|
|
|
+ // Escape colons from IDs, such as those found in Markdown footnote links.
|
|
|
+ target = target.replace(/:/g, '\\:');
|
|
|
+
|
|
|
+ // If target element exists, scroll to it taking into account fixed navigation bar offset.
|
|
|
+ if($(target).length) {
|
|
|
+ $('body').addClass('scrolling');
|
|
|
+ $('html, body').animate({
|
|
|
+ scrollTop: $(target).offset().top - navbar_offset
|
|
|
+ }, 600, function () {
|
|
|
+ $('body').removeClass('scrolling');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Make Scrollspy responsive.
|
|
|
+ function fixScrollspy() {
|
|
|
+ let $body = $('body');
|
|
|
+ let data = $body.data('bs.scrollspy');
|
|
|
+ if (data) {
|
|
|
+ data.options.offset = navbar_offset;
|
|
|
+ $body.data('bs.scrollspy', data);
|
|
|
+ $body.scrollspy('refresh');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check for hash change event and fix responsive offset for hash links (e.g. Markdown footnotes).
|
|
|
+ window.addEventListener("hashchange", scrollToAnchor);
|
|
|
+
|
|
|
+ /* ---------------------------------------------------------------------------
|
|
|
+ * Add smooth scrolling to all links inside the main navbar.
|
|
|
+ * --------------------------------------------------------------------------- */
|
|
|
|
|
|
+ $('#navbar-main li.nav-item a').on('click', function(event) {
|
|
|
// Store requested URL hash.
|
|
|
- var hash = this.hash;
|
|
|
+ let hash = this.hash;
|
|
|
|
|
|
// If we are on the homepage and the navigation bar link is to a homepage section.
|
|
|
- if( hash && $(hash).length && ($("#homepage").length > 0)){
|
|
|
- // Prevent default click behavior
|
|
|
+ if ( hash && $(hash).length && ($("#homepage").length > 0)) {
|
|
|
+ // Prevent default click behavior.
|
|
|
event.preventDefault();
|
|
|
|
|
|
- var navbarHeight = $('.navbar-header').innerHeight();
|
|
|
-
|
|
|
// Use jQuery's animate() method for smooth page scrolling.
|
|
|
// The numerical parameter specifies the time (ms) taken to scroll to the specified hash.
|
|
|
$('html, body').animate({
|
|
|
- scrollTop: $(hash).offset().top - navbarHeight
|
|
|
- }, 800, function () {
|
|
|
- // Add hash (#) to URL once finished scrolling to hash position
|
|
|
- if (hash == "#top"){
|
|
|
- window.location.hash = ""
|
|
|
- }else {
|
|
|
- window.location.hash = hash;
|
|
|
- }
|
|
|
- });
|
|
|
+ scrollTop: $(hash).offset().top - navbar_offset
|
|
|
+ }, 800);
|
|
|
}
|
|
|
});
|
|
|
|
|
@@ -40,51 +75,21 @@
|
|
|
* Smooth scrolling for Back To Top link.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- $('#back_to_top').on('click', function(event){
|
|
|
+ $('#back_to_top').on('click', function(event) {
|
|
|
event.preventDefault();
|
|
|
-
|
|
|
$('html, body').animate({
|
|
|
'scrollTop': 0
|
|
|
- }, 800, function(){
|
|
|
- window.location.hash = ""
|
|
|
+ }, 800, function() {
|
|
|
+ window.location.hash = "";
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- /* ---------------------------------------------------------------------------
|
|
|
- * Smooth scrolling for mouse wheel.
|
|
|
- * --------------------------------------------------------------------------- */
|
|
|
-
|
|
|
- function smoothScroll(scrollTime, scrollDistance){
|
|
|
-
|
|
|
- if (navigator.userAgent.indexOf('Mac') != -1 || navigator.userAgent.indexOf('Firefox') > -1 || jQuery('body').hasClass('is-horizontal')){
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- jQuery(window).on("mousewheel DOMMouseScroll", function(event){
|
|
|
-
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- var delta = event.originalEvent.wheelDelta/120 || -event.originalEvent.detail/3;
|
|
|
- var scrollTop = jQuery(window).scrollTop();
|
|
|
- var finalScroll = scrollTop - parseInt(delta*scrollDistance);
|
|
|
-
|
|
|
- TweenMax.to(jQuery(window), scrollTime, {
|
|
|
- scrollTo : { y: finalScroll, autoKill:true },
|
|
|
- ease: Expo.easeOut,
|
|
|
- autoKill: true,
|
|
|
- overwrite: 5
|
|
|
- });
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
* Hide mobile collapsable menu on clicking a link.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- $(document).on('click','.navbar-collapse.in',function(e){
|
|
|
- if( $(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle' ){
|
|
|
+ $(document).on('click', '.navbar-collapse.in', function(e) {
|
|
|
+ if ( $(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle' ) {
|
|
|
$(this).collapse('hide');
|
|
|
}
|
|
|
});
|
|
@@ -93,7 +98,7 @@
|
|
|
* Filter projects.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- var $grid_projects = $('#container-projects');
|
|
|
+ let $grid_projects = $('#container-projects');
|
|
|
$grid_projects.imagesLoaded(function () {
|
|
|
// Initialize Isotope after all images have loaded.
|
|
|
$grid_projects.isotope({
|
|
@@ -103,18 +108,18 @@
|
|
|
|
|
|
// Filter items when filter link is clicked.
|
|
|
$('#filters a').click(function () {
|
|
|
- var selector = $(this).attr('data-filter');
|
|
|
+ let selector = $(this).attr('data-filter');
|
|
|
$grid_projects.isotope({filter: selector});
|
|
|
- $(this).removeClass('active').addClass('active').siblings().removeClass('active all');
|
|
|
- return false;
|
|
|
- });
|
|
|
+ $(this).removeClass('active').addClass('active').siblings().removeClass('active all');
|
|
|
+ return false;
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
/* ---------------------------------------------------------------------------
|
|
|
* Filter publications.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- var $grid_pubs = $('#container-publications');
|
|
|
+ let $grid_pubs = $('#container-publications');
|
|
|
$grid_pubs.isotope({
|
|
|
itemSelector: '.isotope-item',
|
|
|
percentPosition: true,
|
|
@@ -125,14 +130,14 @@
|
|
|
});
|
|
|
|
|
|
// Bind publication filter on dropdown change.
|
|
|
- $('.pub-filters-select').on( 'change', function() {
|
|
|
+ $('.pub-filters-select').on('change', function() {
|
|
|
// Get filter value from option value.
|
|
|
- var filterValue = this.value;
|
|
|
+ let filterValue = this.value;
|
|
|
// Apply filter to Isotope.
|
|
|
$grid_pubs.isotope({ filter: filterValue });
|
|
|
|
|
|
// Set hash URL to current filter.
|
|
|
- var url = $(this).val();
|
|
|
+ let url = $(this).val();
|
|
|
if (url.substr(0, 9) == '.pubtype-') {
|
|
|
window.location.hash = url.substr(9);
|
|
|
} else {
|
|
@@ -142,8 +147,8 @@
|
|
|
|
|
|
// Filter publications according to hash in URL.
|
|
|
function filter_publications() {
|
|
|
- var urlHash = window.location.hash.replace('#','');
|
|
|
- var filterValue = '*';
|
|
|
+ let urlHash = window.location.hash.replace('#','');
|
|
|
+ let filterValue = '*';
|
|
|
|
|
|
// Check if hash is numeric.
|
|
|
if (urlHash != '' && !isNaN(urlHash)) {
|
|
@@ -158,48 +163,36 @@
|
|
|
* On window load.
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
- $(window).load(function(){
|
|
|
+ $(window).on('load', function() {
|
|
|
|
|
|
- // When accessing publication index, enable filtering.
|
|
|
- if ($('.pub-filters-select')) {
|
|
|
- filter_publications();
|
|
|
-
|
|
|
- // Useful for changing hash manually (e.g. in development):
|
|
|
- // window.addEventListener('hashchange', filter_publications, false);
|
|
|
- }
|
|
|
-
|
|
|
- // Enable smooth scrolling with mouse wheel
|
|
|
- smoothScroll(1.3, 220);
|
|
|
-
|
|
|
- // When accessing homepage from another page and `#top` hash is set, show top of page (no hash).
|
|
|
- if (window.location.hash == "#top") {
|
|
|
- window.location.hash = ""
|
|
|
+ if (window.location.hash) {
|
|
|
+ // When accessing homepage from another page and `#top` hash is set, show top of page (no hash).
|
|
|
+ if (window.location.hash == "#top") {
|
|
|
+ window.location.hash = ""
|
|
|
+ } else {
|
|
|
+ // If URL contains a hash, scroll to target ID taking into account responsive offset.
|
|
|
+ scrollToAnchor();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Initialize Scrollspy.
|
|
|
- var $body = $('body');
|
|
|
- var $navbar = $('.navbar-header');
|
|
|
- var navbar_offset = $navbar.innerHeight() + 1;
|
|
|
+ let $body = $('body');
|
|
|
$body.scrollspy({offset: navbar_offset });
|
|
|
|
|
|
- // Make Scrollspy responsive.
|
|
|
- function fixScrollspy() {
|
|
|
- var data = $body.data('bs.scrollspy');
|
|
|
- if (data) {
|
|
|
- navbar_offset = $navbar.innerHeight() + 1;
|
|
|
- data.options.offset = navbar_offset;
|
|
|
- $body.data('bs.scrollspy', data);
|
|
|
- $body.scrollspy('refresh');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// Call `fixScrollspy` when window is resized.
|
|
|
- var resizeTimer;
|
|
|
+ let resizeTimer;
|
|
|
$(window).resize(function() {
|
|
|
clearTimeout(resizeTimer);
|
|
|
resizeTimer = setTimeout(fixScrollspy, 200);
|
|
|
});
|
|
|
|
|
|
+ // Enable publication filter for publication index page.
|
|
|
+ if ($('.pub-filters-select')) {
|
|
|
+ filter_publications();
|
|
|
+ // Useful for changing hash manually (e.g. in development):
|
|
|
+ // window.addEventListener('hashchange', filter_publications, false);
|
|
|
+ }
|
|
|
+
|
|
|
});
|
|
|
|
|
|
})(jQuery);
|