From 6e602213e7b1fb239cc5f177453025e0740ca5af Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Sun, 21 Jun 2020 11:01:28 +0800 Subject: [PATCH] Fix compatibility issue with iOS 10-12 --- .../css/_common/outline/sidebar/sidebar.styl | 10 -- source/css/_schemes/Muse/_sidebar.styl | 7 ++ source/css/_schemes/Pisces/_sidebar.styl | 1 + source/js/algolia-search.js | 6 +- source/js/local-search.js | 3 +- source/js/utils.js | 100 ++++++------------ 6 files changed, 48 insertions(+), 79 deletions(-) diff --git a/source/css/_common/outline/sidebar/sidebar.styl b/source/css/_common/outline/sidebar/sidebar.styl index 40f5979..9716f27 100644 --- a/source/css/_common/outline/sidebar/sidebar.styl +++ b/source/css/_common/outline/sidebar/sidebar.styl @@ -1,13 +1,3 @@ -.sidebar { - background: $black-deep; - bottom: 0; - if (!hexo-config('back2top.sidebar')) { - box-shadow: inset 0 2px 6px black; - } - position: fixed; - top: 0; -} - .sidebar-inner { color: $grey-dark; padding: $sidebar-padding 10px; diff --git a/source/css/_schemes/Muse/_sidebar.styl b/source/css/_schemes/Muse/_sidebar.styl index 393b590..f2028ce 100644 --- a/source/css/_schemes/Muse/_sidebar.styl +++ b/source/css/_schemes/Muse/_sidebar.styl @@ -29,6 +29,13 @@ if (hexo-config('sidebar.position') == 'right') { } .sidebar { + background: $black-deep; + bottom: 0; + if (!hexo-config('back2top.sidebar')) { + box-shadow: inset 0 2px 6px black; + } + position: fixed; + top: 0; transition: all $transition-ease-out; width: $sidebar-desktop; z-index: $zindex-2; diff --git a/source/css/_schemes/Pisces/_sidebar.styl b/source/css/_schemes/Pisces/_sidebar.styl index 64184c7..0b487bf 100644 --- a/source/css/_schemes/Pisces/_sidebar.styl +++ b/source/css/_schemes/Pisces/_sidebar.styl @@ -3,6 +3,7 @@ bottom: initial; box-shadow: none; margin-top: $sidebar-offset; + position: -webkit-sticky; position: sticky; top: $sidebar-offset; width: $sidebar-desktop; diff --git a/source/js/algolia-search.js b/source/js/algolia-search.js index b26cae7..3596817 100644 --- a/source/js/algolia-search.js +++ b/source/js/algolia-search.js @@ -3,13 +3,13 @@ document.addEventListener('DOMContentLoaded', () => { const algoliaSettings = CONFIG.algolia; const { indexName, appID, apiKey } = algoliaSettings; + const input = document.querySelector('.search-input'); let search = instantsearch({ indexName, searchClient : algoliasearch(appID, apiKey), searchFunction: helper => { - let searchInput = document.querySelector('.search-input'); - if (searchInput.value) { + if (input.value) { helper.search(); } } @@ -98,7 +98,7 @@ document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.popup-trigger').forEach(element => { element.addEventListener('click', () => { document.body.classList.add('search-active'); - document.querySelector('.search-input').focus(); + setTimeout(() => input.focus(), 500); }); }); diff --git a/source/js/local-search.js b/source/js/local-search.js index 76167b9..48541bf 100644 --- a/source/js/local-search.js +++ b/source/js/local-search.js @@ -251,7 +251,8 @@ document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.popup-trigger').forEach(element => { element.addEventListener('click', () => { document.body.classList.add('search-active'); - input.focus(); + // Wait for search-popup animation to complete + setTimeout(() => input.focus(), 500); if (!isfetched) fetchData(); }); }); diff --git a/source/js/utils.js b/source/js/utils.js index a846725..f086527 100644 --- a/source/js/utils.js +++ b/source/js/utils.js @@ -131,7 +131,6 @@ NexT.utils = { }, registerScrollPercent: function() { - const THRESHOLD = 50; const backToTop = document.querySelector('.back-to-top'); const readingProgressBar = document.querySelector('.reading-progress-bar'); // For init back to top in sidebar if page was scrolled after page refresh. @@ -142,13 +141,23 @@ NexT.utils = { const contentVisibilityHeight = docHeight > winHeight ? docHeight - winHeight : document.body.scrollHeight - winHeight; const scrollPercent = Math.min(100 * window.scrollY / contentVisibilityHeight, 100); if (backToTop) { - backToTop.classList.toggle('back-to-top-on', window.scrollY > THRESHOLD); + backToTop.classList.toggle('back-to-top-on', Math.round(scrollPercent) >= 5); backToTop.querySelector('span').innerText = Math.round(scrollPercent) + '%'; } if (readingProgressBar) { readingProgressBar.style.width = scrollPercent.toFixed(2) + '%'; } } + if (!Array.isArray(NexT.utils.sections)) return; + let index = NexT.utils.sections.findIndex(element => { + return element && element.getBoundingClientRect().top > 0; + }); + if (index === -1) { + index = NexT.utils.sections.length - 1; + } else if (index > 0) { + index--; + } + this.activateNavByIndex(index); }); backToTop && backToTop.addEventListener('click', () => { @@ -224,12 +233,10 @@ NexT.utils = { }, registerSidebarTOC: function() { - const navItems = document.querySelectorAll('.post-toc li'); - const sections = [...navItems].map(element => { - const link = element.querySelector('a.nav-link'); - const target = document.getElementById(decodeURI(link.getAttribute('href')).replace('#', '')); + this.sections = [...document.querySelectorAll('.post-toc li a.nav-link')].map(element => { + const target = document.getElementById(decodeURI(element.getAttribute('href')).replace('#', '')); // TOC item animation navigate. - link.addEventListener('click', event => { + element.addEventListener('click', event => { event.preventDefault(); const offset = target.getBoundingClientRect().top + window.scrollY; window.anime({ @@ -241,66 +248,29 @@ NexT.utils = { }); return target; }); + }, + activateNavByIndex: function(index) { + const target = document.querySelectorAll('.post-toc li a.nav-link')[index]; + if (!target || target.classList.contains('active-current')) return; + + document.querySelectorAll('.post-toc .active').forEach(element => { + element.classList.remove('active', 'active-current'); + }); + target.classList.add('active', 'active-current'); + let parent = target.parentNode; + while (!parent.matches('.post-toc')) { + if (parent.matches('li')) parent.classList.add('active'); + parent = parent.parentNode; + } + // Scrolling to center active TOC element if TOC content is taller then viewport. const tocElement = document.querySelector('.post-toc-wrap'); - function activateNavByIndex(target) { - if (target.classList.contains('active-current')) return; - - document.querySelectorAll('.post-toc .active').forEach(element => { - element.classList.remove('active', 'active-current'); - }); - target.classList.add('active', 'active-current'); - let parent = target.parentNode; - while (!parent.matches('.post-toc')) { - if (parent.matches('li')) parent.classList.add('active'); - parent = parent.parentNode; - } - // Scrolling to center active TOC element if TOC content is taller then viewport. - window.anime({ - targets : tocElement, - duration : 200, - easing : 'linear', - scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top - }); - } - - function findIndex(entries) { - let index = 0; - let entry = entries[index]; - if (entry.boundingClientRect.top > 0) { - index = sections.indexOf(entry.target); - return index === 0 ? 0 : index - 1; - } - for (; index < entries.length; index++) { - if (entries[index].boundingClientRect.top <= 0) { - entry = entries[index]; - } else { - return sections.indexOf(entry.target); - } - } - return sections.indexOf(entry.target); - } - - function createIntersectionObserver(marginTop) { - marginTop = Math.floor(marginTop + 10000); - let intersectionObserver = new IntersectionObserver((entries, observe) => { - let scrollHeight = document.documentElement.scrollHeight + 100; - if (scrollHeight > marginTop) { - observe.disconnect(); - createIntersectionObserver(scrollHeight); - return; - } - let index = findIndex(entries); - activateNavByIndex(navItems[index]); - }, { - rootMargin: marginTop + 'px 0px -100% 0px', - threshold : 0 - }); - sections.forEach(element => { - element && intersectionObserver.observe(element); - }); - } - createIntersectionObserver(document.documentElement.scrollHeight); + window.anime({ + targets : tocElement, + duration : 200, + easing : 'linear', + scrollTop: tocElement.scrollTop - (tocElement.offsetHeight / 2) + target.getBoundingClientRect().top - tocElement.getBoundingClientRect().top + }); }, supportsPDFs: function() {