diff --git a/src/theme/book.js b/src/theme/book.js index 8ddd09d55f..8fda7a6cbe 100644 --- a/src/theme/book.js +++ b/src/theme/book.js @@ -580,26 +580,60 @@ function playpen_text(playpen) { }); })(); -(function autoHideMenu() { +(function controllMenu() { var menu = document.getElementById('menu-bar'); - var previousScrollTop = document.scrollingElement.scrollTop; - - document.addEventListener('scroll', function () { - if (menu.classList.contains('folded') && document.scrollingElement.scrollTop < previousScrollTop) { - menu.classList.remove('folded'); - } else if (!menu.classList.contains('folded') && document.scrollingElement.scrollTop > previousScrollTop) { - menu.classList.add('folded'); - } - - if (!menu.classList.contains('bordered') && document.scrollingElement.scrollTop > 0) { - menu.classList.add('bordered'); - } - - if (menu.classList.contains('bordered') && document.scrollingElement.scrollTop === 0) { - menu.classList.remove('bordered'); - } - - previousScrollTop = Math.max(document.scrollingElement.scrollTop, 0); - }, { passive: true }); + (function controllPosition() { + var scrollTop = document.scrollingElement.scrollTop; + var prevScrollTop = scrollTop; + var minMenuY = -menu.clientHeight - 50; + // When the script loads, the page can be at any scroll (e.g. if you reforesh it). + menu.style.top = scrollTop + 'px'; + // Same as parseInt(menu.style.top.slice(0, -2), but faster + var topCache = menu.style.top.slice(0, -2); + menu.classList.remove('sticky'); + var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster + document.addEventListener('scroll', function () { + scrollTop = Math.max(document.scrollingElement.scrollTop, 0); + // `null` means that it doesn't need to be updated + var nextSticky = null; + var nextTop = null; + var scrollDown = scrollTop > prevScrollTop; + var menuPosAbsoluteY = topCache - scrollTop; + if (scrollDown) { + nextSticky = false; + if (menuPosAbsoluteY > 0) { + nextTop = prevScrollTop; + } + } else { + if (menuPosAbsoluteY > 0) { + nextSticky = true; + } else if (menuPosAbsoluteY < minMenuY) { + nextTop = prevScrollTop + minMenuY; + } + } + if (nextSticky === true && stickyCache === false) { + menu.classList.add('sticky'); + stickyCache = true; + } else if (nextSticky === false && stickyCache === true) { + menu.classList.remove('sticky'); + stickyCache = false; + } + if (nextTop !== null) { + menu.style.top = nextTop + 'px'; + topCache = nextTop; + } + prevScrollTop = scrollTop; + }, { passive: true }); + })(); + (function controllBorder() { + menu.classList.remove('bordered'); + document.addEventListener('scroll', function () { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + }, { passive: true }); + })(); })(); diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css index af4fd62c5c..33ca3ab5ca 100644 --- a/src/theme/css/chrome.css +++ b/src/theme/css/chrome.css @@ -20,14 +20,13 @@ a > .hljs { /* Menu Bar */ -#menu-bar { - position: -webkit-sticky; - position: sticky; - top: 0; +#menu-bar, +#menu-bar-hover-placeholder { z-index: 101; margin: auto calc(0px - var(--page-padding)); } -#menu-bar > #menu-bar-sticky-container { +#menu-bar { + position: relative; display: flex; flex-wrap: wrap; background-color: var(--bg); @@ -35,10 +34,21 @@ a > .hljs { border-bottom-width: 1px; border-bottom-style: solid; } -.js #menu-bar > #menu-bar-sticky-container { - transition: transform 0.3s; +#menu-bar.sticky, +.js #menu-bar-hover-placeholder:hover + #menu-bar, +.js #menu-bar:hover, +.js.sidebar-visible #menu-bar { + position: -webkit-sticky; + position: sticky; + top: 0 !important; +} +#menu-bar-hover-placeholder { + position: sticky; + position: -webkit-sticky; + top: 0; + height: var(--menu-bar-height); } -#menu-bar.bordered > #menu-bar-sticky-container { +#menu-bar.bordered { border-bottom-color: var(--table-border-color); } #menu-bar i, #menu-bar .icon-button { @@ -72,10 +82,6 @@ a > .hljs { text-decoration: none; } -html:not(.sidebar-visible) #menu-bar:not(:hover).folded > #menu-bar-sticky-container { - transform: translateY(calc(-10px - var(--menu-bar-height))); -} - .left-buttons { display: flex; margin: 0 5px; diff --git a/src/theme/css/general.css b/src/theme/css/general.css index e0bb85147c..0eff0a3cc9 100644 --- a/src/theme/css/general.css +++ b/src/theme/css/general.css @@ -60,6 +60,7 @@ h4 a.header:target { .page { outline: 0; padding: 0 var(--page-padding); + margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ } .page-wrapper { box-sizing: border-box; diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 8b362342ab..8f586e01d1 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -97,41 +97,40 @@
{{> header}} -