Skip to content

Commit

Permalink
Merge pull request matcornic#46 from lfalin/anchor-fix
Browse files Browse the repository at this point in the history
Fix anchor scrolling that hides behind top nav bar
  • Loading branch information
matcornic authored May 29, 2017
2 parents ede44c1 + 05c64bd commit 2161b3c
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions static/js/learn.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,94 @@ jQuery(document).ready(function() {
$('.progress').hover(function() {
$('.progress').stop(true, false, true).fadeToggle(100);
});

/**
* Fix anchor scrolling that hides behind top nav bar
* Courtesy of https://stackoverflow.com/a/13067009/28106
*
* We could use pure css for this if only heading anchors were
* involved, but this works for any anchor, including footnotes
**/
(function(document, history, location) {
var HISTORY_SUPPORT = !!(history && history.pushState);

var anchorScrolls = {
ANCHOR_REGEX: /^#[^ ]+$/,
OFFSET_HEIGHT_PX: 50,

/**
* Establish events, and fix initial scroll position if a hash is provided.
*/
init: function() {
this.scrollToCurrent();
window.addEventListener('hashchange', this.scrollToCurrent.bind(this));
document.body.addEventListener('click', this.delegateAnchors.bind(this));
},

/**
* Return the offset amount to deduct from the normal scroll position.
* Modify as appropriate to allow for dynamic calculations
*/
getFixedOffset: function() {
return this.OFFSET_HEIGHT_PX;
},

/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
* @param {String} href
* @return {Boolean} - Was the href an anchor.
*/
scrollIfAnchor: function(href, pushToHistory) {
var match, rect, anchorOffset;

if(!this.ANCHOR_REGEX.test(href)) {
return false;
}

match = document.getElementById(href.slice(1));

if(match) {
rect = match.getBoundingClientRect();
anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset();
window.scrollTo(window.pageXOffset, anchorOffset);

// Add the state to history as-per normal anchor links
if(HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href);
}
}

return !!match;
},

/**
* Attempt to scroll to the current location's hash.
*/
scrollToCurrent: function() {
this.scrollIfAnchor(window.location.hash);
},

/**
* If the click event's target was an anchor, fix the scroll position.
*/
delegateAnchors: function(e) {
var elem = e.target;

if(
elem.nodeName === 'A' &&
this.scrollIfAnchor(elem.getAttribute('href'), true)
) {
e.preventDefault();
}
}
};

window.addEventListener(
'DOMContentLoaded', anchorScrolls.init.bind(anchorScrolls)
);
})(window.document, window.history, window.location);

});

jQuery(window).on('load', function() {
Expand Down

0 comments on commit 2161b3c

Please sign in to comment.