From bc3336ba503b7013580b95d111dbd3ed3c09ce4e Mon Sep 17 00:00:00 2001 From: Ryan Rivest Date: Thu, 26 Apr 2018 19:57:16 -0400 Subject: [PATCH 1/7] add active sidebar link highlight --- lib/default-theme/Layout.vue | 39 +++++++++++++++++++++++++++++++++++- package.json | 1 + 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index f45e52e236..c0bf849725 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -29,6 +29,7 @@ import Page from './Page.vue' import Sidebar from './Sidebar.vue' import { pathToComponentName } from '@app/util' import { resolveSidebarItems } from './util' +import throttle from 'lodash/throttle' export default { components: { Home, Page, Sidebar, Navbar }, @@ -111,6 +112,8 @@ export default { this.$watch('$page', updateMeta) updateMeta() + window.addEventListener('scroll', this.onScroll) + // configure progress bar nprogress.configure({ showSpinner: false }) @@ -129,6 +132,8 @@ export default { beforeDestroy () { updateMetaTags(null, this.currentMetaTags) + + window.removeEventListener('scroll', this.onScroll) }, methods: { @@ -152,7 +157,10 @@ export default { this.toggleSidebar(false) } } - } + }, + onScroll: throttle(() => { + setActiveHash() + }, 200) } } @@ -173,6 +181,35 @@ function updateMetaTags (meta, current) { }) } } + +function setActiveHash () { + const anchors = gatherHeaderAnchors() + + const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) + + for (let i = 0; i < anchors.length; i++) { + const anchor = anchors[i] + const nextAnchor = anchors[i + 1] + + const isActive = i === 0 && scrollTop === 0 || + (scrollTop >= anchor.parentElement.offsetTop + 10 && + (typeof nextAnchor === 'undefined' || scrollTop < nextAnchor.parentElement.offsetTop - 10)) + + if (isActive && window.location.hash !== anchor.hash) { + window.location.hash = anchor.hash + return + } + } +} + +function gatherHeaderAnchors () { + const sidebarLinks = Array.from(document.querySelectorAll('.sidebar-group-items a.sidebar-link')) + + const anchors = Array.from(document.querySelectorAll('a.header-anchor')) + .filter(x => sidebarLinks.map(x => x.hash).includes(x.hash)) + + return anchors +} diff --git a/package.json b/package.json index 441450d921..18686e7a1b 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "koa-mount": "^3.0.0", "koa-static": "^4.0.2", "loader-utils": "^1.1.0", + "lodash.throttle": "^4.1.1", "lru-cache": "^4.1.2", "markdown-it": "^8.4.1", "markdown-it-anchor": "^4.0.0", From 30800acaba2333e2f923e74d8414aebf01718d56 Mon Sep 17 00:00:00 2001 From: Ryan Rivest Date: Thu, 26 Apr 2018 22:14:02 -0400 Subject: [PATCH 2/7] use router to update hash --- lib/app/app.js | 4 ++- lib/default-theme/Layout.vue | 47 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/lib/app/app.js b/lib/app/app.js index 8040f5fc7a..c10b5307d8 100644 --- a/lib/app/app.js +++ b/lib/app/app.js @@ -57,7 +57,9 @@ export function createApp () { if (saved) { return saved } else if (to.hash) { - return { selector: to.hash } + return false + // temp: removed for testing + // return { selector: to.hash } } else { return { x: 0, y: 0 } } diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index c0bf849725..b7b126f422 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -158,9 +158,28 @@ export default { } } }, - onScroll: throttle(() => { - setActiveHash() - }, 200) + onScroll: throttle(function () { + this.setActiveHash() + }, 200), + setActiveHash () { + const anchors = gatherHeaderAnchors() + + const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) + + for (let i = 0; i < anchors.length; i++) { + const anchor = anchors[i] + const nextAnchor = anchors[i + 1] + + const isActive = i === 0 && scrollTop === 0 || + (scrollTop >= anchor.parentElement.offsetTop + 10 && + (typeof nextAnchor === 'undefined' || scrollTop < nextAnchor.parentElement.offsetTop - 10)) + + if (isActive && this.$route.hash !== anchor.hash) { + this.$router.replace(anchor.hash) + return + } + } + } } } @@ -182,31 +201,11 @@ function updateMetaTags (meta, current) { } } -function setActiveHash () { - const anchors = gatherHeaderAnchors() - - const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) - - for (let i = 0; i < anchors.length; i++) { - const anchor = anchors[i] - const nextAnchor = anchors[i + 1] - - const isActive = i === 0 && scrollTop === 0 || - (scrollTop >= anchor.parentElement.offsetTop + 10 && - (typeof nextAnchor === 'undefined' || scrollTop < nextAnchor.parentElement.offsetTop - 10)) - - if (isActive && window.location.hash !== anchor.hash) { - window.location.hash = anchor.hash - return - } - } -} - function gatherHeaderAnchors () { const sidebarLinks = Array.from(document.querySelectorAll('.sidebar-group-items a.sidebar-link')) const anchors = Array.from(document.querySelectorAll('a.header-anchor')) - .filter(x => sidebarLinks.map(x => x.hash).includes(x.hash)) + .filter(x => sidebarLinks.map(x => x.hash).some(hash => hash === x.hash)) return anchors } From ffdd8b7da86823790353ef0053413ce42adadb9d Mon Sep 17 00:00:00 2001 From: Ryan Rivest Date: Fri, 27 Apr 2018 10:25:09 -0400 Subject: [PATCH 3/7] update throttle import --- lib/default-theme/Layout.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index b7b126f422..8f35d30cd6 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -29,7 +29,7 @@ import Page from './Page.vue' import Sidebar from './Sidebar.vue' import { pathToComponentName } from '@app/util' import { resolveSidebarItems } from './util' -import throttle from 'lodash/throttle' +import throttle from 'lodash.throttle' export default { components: { Home, Page, Sidebar, Navbar }, From 7ca5f5c69c9f656f53f8063e93b7a747a8689394 Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 27 Apr 2018 22:48:01 +0800 Subject: [PATCH 4/7] chore: remove comments --- lib/app/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/app/app.js b/lib/app/app.js index c10b5307d8..924a966356 100644 --- a/lib/app/app.js +++ b/lib/app/app.js @@ -58,8 +58,6 @@ export function createApp () { return saved } else if (to.hash) { return false - // temp: removed for testing - // return { selector: to.hash } } else { return { x: 0, y: 0 } } From c67c64ac59150b56979a5ad503fed6b08c07f61a Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 27 Apr 2018 22:51:31 +0800 Subject: [PATCH 5/7] chore: simplify code --- lib/default-theme/Layout.vue | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index 8f35d30cd6..c38b9daba3 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -162,8 +162,7 @@ export default { this.setActiveHash() }, 200), setActiveHash () { - const anchors = gatherHeaderAnchors() - + const anchors = document.querySelectorAll('.header-anchor') const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) for (let i = 0; i < anchors.length; i++) { @@ -172,7 +171,7 @@ export default { const isActive = i === 0 && scrollTop === 0 || (scrollTop >= anchor.parentElement.offsetTop + 10 && - (typeof nextAnchor === 'undefined' || scrollTop < nextAnchor.parentElement.offsetTop - 10)) + (!nextAnchor || scrollTop < nextAnchor.parentElement.offsetTop - 10)) if (isActive && this.$route.hash !== anchor.hash) { this.$router.replace(anchor.hash) @@ -200,15 +199,6 @@ function updateMetaTags (meta, current) { }) } } - -function gatherHeaderAnchors () { - const sidebarLinks = Array.from(document.querySelectorAll('.sidebar-group-items a.sidebar-link')) - - const anchors = Array.from(document.querySelectorAll('a.header-anchor')) - .filter(x => sidebarLinks.map(x => x.hash).some(hash => hash === x.hash)) - - return anchors -} From 58f4b028b28d33a317fcd6540195576711498395 Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 27 Apr 2018 22:54:50 +0800 Subject: [PATCH 6/7] chore: change throttle duration from 200 to 300 --- lib/default-theme/Layout.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index c38b9daba3..0c821609ab 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -160,7 +160,7 @@ export default { }, onScroll: throttle(function () { this.setActiveHash() - }, 200), + }, 300), setActiveHash () { const anchors = document.querySelectorAll('.header-anchor') const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) From 1c4c376624b911600d007fe88f8d5851b9758267 Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 27 Apr 2018 23:21:20 +0800 Subject: [PATCH 7/7] chore: tweaks --- lib/default-theme/Layout.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/default-theme/Layout.vue b/lib/default-theme/Layout.vue index 0c821609ab..7ad99f1190 100644 --- a/lib/default-theme/Layout.vue +++ b/lib/default-theme/Layout.vue @@ -162,7 +162,10 @@ export default { this.setActiveHash() }, 300), setActiveHash () { - const anchors = document.querySelectorAll('.header-anchor') + const sidebarLinks = [].slice.call(document.querySelectorAll('.sidebar-link')) + const anchors = [].slice.call(document.querySelectorAll('.header-anchor')) + .filter(anchor => sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash)) + const scrollTop = Math.max(window.pageYOffset, document.documentElement.scrollTop, document.body.scrollTop) for (let i = 0; i < anchors.length; i++) {