mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2025-01-18 19:00:24 +00:00
Merge pull request #46 from lfalin/anchor-fix
Fix anchor scrolling that hides behind top nav bar
This commit is contained in:
commit
aacdba800a
1 changed files with 88 additions and 0 deletions
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue