fix(scroll) highlight bug
This commit is contained in:
parent
46ff5e14bf
commit
6b08546654
3 changed files with 56 additions and 53 deletions
|
|
@ -2,17 +2,62 @@ import { isMobile } from '../util/env'
|
||||||
import * as dom from '../util/dom'
|
import * as dom from '../util/dom'
|
||||||
import { parse } from '../route/hash'
|
import { parse } from '../route/hash'
|
||||||
|
|
||||||
|
const nav = {}
|
||||||
|
let hoverOver = false
|
||||||
|
|
||||||
|
function highlight () {
|
||||||
|
const sidebar = dom.getNode('.sidebar')
|
||||||
|
const anchors = dom.findAll('.anchor')
|
||||||
|
const wrap = dom.find(sidebar, '.sidebar-nav')
|
||||||
|
let active = dom.find(sidebar, 'li.active')
|
||||||
|
const top = dom.body.scrollTop
|
||||||
|
let last
|
||||||
|
|
||||||
|
for (let i = 0, len = anchors.length; i < len; i += 1) {
|
||||||
|
const node = anchors[i]
|
||||||
|
|
||||||
|
if (node.offsetTop > top) {
|
||||||
|
if (!last) last = node
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
last = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!last) return
|
||||||
|
const li = nav[last.getAttribute('data-id')]
|
||||||
|
|
||||||
|
if (!li || li === active) return
|
||||||
|
|
||||||
|
active && active.classList.remove('active')
|
||||||
|
li.classList.add('active')
|
||||||
|
active = li
|
||||||
|
|
||||||
|
// scroll into view
|
||||||
|
// https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297
|
||||||
|
if (!hoverOver && dom.body.classList.contains('sticky')) {
|
||||||
|
const height = sidebar.clientHeight
|
||||||
|
const curOffset = 0
|
||||||
|
const cur = active.offsetTop + active.clientHeight + 40
|
||||||
|
const isInView = (
|
||||||
|
active.offsetTop >= wrap.scrollTop &&
|
||||||
|
cur <= wrap.scrollTop + height
|
||||||
|
)
|
||||||
|
const notThan = cur - curOffset < height
|
||||||
|
const top = isInView
|
||||||
|
? wrap.scrollTop
|
||||||
|
: notThan
|
||||||
|
? curOffset
|
||||||
|
: cur - height
|
||||||
|
|
||||||
|
sidebar.scrollTop = top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function scrollActiveSidebar () {
|
export function scrollActiveSidebar () {
|
||||||
if (isMobile) return
|
if (isMobile) return
|
||||||
|
|
||||||
let hoverOver = false
|
const sidebar = dom.getNode('.sidebar')
|
||||||
const anchors = dom.findAll('.anchor')
|
|
||||||
const sidebar = dom.find('.sidebar')
|
|
||||||
const wrap = dom.find(sidebar, '.sidebar-nav')
|
|
||||||
|
|
||||||
const nav = {}
|
|
||||||
const lis = dom.findAll(sidebar, 'li')
|
const lis = dom.findAll(sidebar, 'li')
|
||||||
let active = dom.find(sidebar, 'li.active')
|
|
||||||
|
|
||||||
for (let i = 0, len = lis.length; i < len; i += 1) {
|
for (let i = 0, len = lis.length; i < len; i += 1) {
|
||||||
const li = lis[i]
|
const li = lis[i]
|
||||||
|
|
@ -27,50 +72,6 @@ export function scrollActiveSidebar () {
|
||||||
nav[decodeURIComponent(href)] = li
|
nav[decodeURIComponent(href)] = li
|
||||||
}
|
}
|
||||||
|
|
||||||
function highlight () {
|
|
||||||
const top = dom.body.scrollTop
|
|
||||||
let last
|
|
||||||
|
|
||||||
for (let i = 0, len = anchors.length; i < len; i += 1) {
|
|
||||||
const node = anchors[i]
|
|
||||||
|
|
||||||
if (node.offsetTop > top) {
|
|
||||||
if (!last) last = node
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
last = node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!last) return
|
|
||||||
const li = nav[last.getAttribute('data-id')]
|
|
||||||
|
|
||||||
if (!li || li === active) return
|
|
||||||
|
|
||||||
active && active.classList.remove('active')
|
|
||||||
li.classList.add('active')
|
|
||||||
active = li
|
|
||||||
|
|
||||||
// scroll into view
|
|
||||||
// https://github.com/vuejs/vuejs.org/blob/master/themes/vue/source/js/common.js#L282-L297
|
|
||||||
if (!hoverOver && dom.body.classList.contains('sticky')) {
|
|
||||||
const height = sidebar.clientHeight
|
|
||||||
const curOffset = 0
|
|
||||||
const cur = active.offsetTop + active.clientHeight + 40
|
|
||||||
const isInView = (
|
|
||||||
active.offsetTop >= wrap.scrollTop &&
|
|
||||||
cur <= wrap.scrollTop + height
|
|
||||||
)
|
|
||||||
const notThan = cur - curOffset < height
|
|
||||||
const top = isInView
|
|
||||||
? wrap.scrollTop
|
|
||||||
: notThan
|
|
||||||
? curOffset
|
|
||||||
: cur - height
|
|
||||||
|
|
||||||
sidebar.scrollTop = top
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dom.off('scroll', highlight)
|
dom.off('scroll', highlight)
|
||||||
dom.on('scroll', highlight)
|
dom.on('scroll', highlight)
|
||||||
dom.on(sidebar, 'mouseover', () => { hoverOver = true })
|
dom.on(sidebar, 'mouseover', () => { hoverOver = true })
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ function renderMain (html) {
|
||||||
// execute script
|
// execute script
|
||||||
this.config.executeScript && executeScript()
|
this.config.executeScript && executeScript()
|
||||||
|
|
||||||
if (!this.config.executeScript &&
|
if (this.config.executeScript !== false &&
|
||||||
typeof window.Vue !== 'undefined' &&
|
typeof window.Vue !== 'undefined' &&
|
||||||
!executeScript()) {
|
!executeScript()) {
|
||||||
setTimeout(_ => {
|
setTimeout(_ => {
|
||||||
|
const vueVM = window.__EXECUTE_RESULT__
|
||||||
|
vueVM && vueVM.$destroy && vueVM.$destroy()
|
||||||
window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main')
|
window.__EXECUTE_RESULT__ = new window.Vue().$mount('#main')
|
||||||
}, 0)
|
}, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ div#app {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
margin: 40vw auto;
|
margin: 40vh auto;
|
||||||
|
|
||||||
&:empty::before {
|
&:empty::before {
|
||||||
content: "Loading...";
|
content: "Loading...";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue