diff --git a/src/js/gumshoe/gumshoe.js b/src/js/gumshoe/gumshoe.js index aca299c..0834f7d 100755 --- a/src/js/gumshoe/gumshoe.js +++ b/src/js/gumshoe/gumshoe.js @@ -26,9 +26,10 @@ nested: false, nestedClass: 'active', - // Offset & reflow + // Offset & reflow & click offset: 0, reflow: false, + click: false, // Event support events: true @@ -161,7 +162,7 @@ * @return {Boolean} If true, page is at the bottom of the viewport */ var isAtBottom = function () { - if (window.innerHeight + window.pageYOffset >= getDocumentHeight()) return true; + if (Math.round(window.innerHeight + window.pageYOffset) >= getDocumentHeight()) return true; return false; }; @@ -374,6 +375,32 @@ }; + /** + * Get which content is clicked and to be activated. + */ + publicAPIs.click = function (clicked) { + + // if there's no active content, deactivate and bail + if (!clicked) { + if (current) { + deactivate(current, settings); + current = null; + } + return; + } + + // If the active content is the one currently active, do nothing + if (current && clicked.content === current.content) return; + + // Deactivate the current content and activate the new content + deactivate(current, settings); + activate(clicked, settings); + + // Update the currently active content + current = clicked; + + }; + /** * Detect the active content on scroll * Debounced for performance @@ -409,6 +436,43 @@ }; + /** + * Add scrollHandler on next scroll + * Not debounced + */ + var attachScrollHandler = function (event) { + window.addEventListener('scroll', scrollHandler, false); + window.removeEventListener('scroll', attachScrollHandler, false); + } + + /** + * Activate content clicked, and deactivate current + * Not debounced + */ + var clickHandler = function (event) { + var nav = event.path[0]; + + // If nav is invalid element + if (!nav || !nav.hash) return; + + // If there's a timer, cancel it + if (timeout) { + window.cancelAnimationFrame(timeout); + } + + sortContents(contents); + + // Block scrollHandler + window.removeEventListener('scroll', scrollHandler, false); + publicAPIs.click({ nav: nav, + content: document.getElementById(decodeURIComponent(nav.hash.substr(1))) + }); + + // Reattach scrollHandler on next scroll-up + window.addEventListener('scroll', attachScrollHandler, false); + + }; + /** * Destroy the current instantiation */ @@ -424,6 +488,9 @@ if (settings.reflow) { window.removeEventListener('resize', resizeHandler, false); } + if (settings.click) { + window.removeEventListener('click', clickHandler, false); + } // Reset variables contents = null; @@ -453,6 +520,9 @@ if (settings.reflow) { window.addEventListener('resize', resizeHandler, false); } + if (settings.click) { + window.addEventListener('click', clickHandler, false); + } };