// Modified from https://stackoverflow.com/a/13067009 // Going for a JS solution to scrolling to an anchor so we can benefit from // less hacky css and smooth scrolling. var scrollToAnchor = { bind: function() { var document = window.document; var history = window.history; var location = window.location var HISTORY_SUPPORT = !!(history && history.pushState); var anchorScrolls = { ANCHOR_REGEX: /^#[^ ]+$/, offsetHeightPx: function() { return $(".header-holder").height() + 20; }, /** * Establish events, and fix initial scroll position if a hash is provided. */ init: function() { this.scrollToCurrent(); $(window).on('hashchange', $.proxy(this, 'scrollToCurrent')); $('body').on('click', 'a', $.proxy(this, 'delegateAnchors')); }, /** * Return the offset amount to deduct from the normal scroll position. * Modify as appropriate to allow for dynamic calculations */ getFixedOffset: function() { return this.offsetHeightPx(); }, /** * 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, anchorOffset; if(!this.ANCHOR_REGEX.test(href)) { return false; } match = document.getElementById(href.slice(1)); if(match) { anchorOffset = $(match).offset().top - this.getFixedOffset(); $('html, body').scrollTop(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(e) { if(this.scrollIfAnchor(window.location.hash) && e) { e.preventDefault(); } }, /** * If the click event's target was an anchor, fix the scroll position. */ delegateAnchors: function(e) { var elem = e.target; if(this.scrollIfAnchor(elem.getAttribute('href'), true)) { e.preventDefault(); } } }; $(document).ready($.proxy(anchorScrolls, 'init')); } };