feat(render): add auto header
This commit is contained in:
parent
fd9c3bd19d
commit
b7768b1b3c
6 changed files with 50 additions and 26 deletions
|
|
@ -14,6 +14,7 @@ const config = merge({
|
||||||
name: '',
|
name: '',
|
||||||
themeColor: '',
|
themeColor: '',
|
||||||
nameLink: window.location.pathname,
|
nameLink: window.location.pathname,
|
||||||
|
autoHeader: false,
|
||||||
ga: ''
|
ga: ''
|
||||||
}, window.$docsify)
|
}, window.$docsify)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,51 @@
|
||||||
import { isMobile } from '../util/env'
|
import { isMobile } from '../util/env'
|
||||||
import { getNode, on, body, findAll, toggleClass } from '../util/dom'
|
import * as dom from '../util/dom'
|
||||||
import { getHash } from '../route/hash'
|
import { getHash } from '../route/hash'
|
||||||
|
|
||||||
|
const title = dom.$.title
|
||||||
/**
|
/**
|
||||||
* Toggle button
|
* Toggle button
|
||||||
*/
|
*/
|
||||||
export function btn (el) {
|
export function btn (el) {
|
||||||
const toggle = () => body.classList.toggle('close')
|
const toggle = () => dom.body.classList.toggle('close')
|
||||||
|
|
||||||
el = getNode(el)
|
el = dom.getNode(el)
|
||||||
on(el, 'click', toggle)
|
dom.on(el, 'click', toggle)
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
const sidebar = getNode('.sidebar')
|
const sidebar = dom.getNode('.sidebar')
|
||||||
|
|
||||||
on(sidebar, 'click', () => {
|
dom.on(sidebar, 'click', () => {
|
||||||
toggle()
|
toggle()
|
||||||
setTimeout(() => getAndActive(true), 0)
|
setTimeout(() => getAndActive(sidebar, true, true), 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sticky () {
|
export function sticky () {
|
||||||
const cover = getNode('section.cover')
|
const cover = dom.getNode('section.cover')
|
||||||
if (!cover) return
|
if (!cover) return
|
||||||
const coverHeight = cover.getBoundingClientRect().height
|
const coverHeight = cover.getBoundingClientRect().height
|
||||||
|
|
||||||
if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) {
|
if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) {
|
||||||
toggleClass(body, 'add', 'sticky')
|
dom.toggleClass(dom.body, 'add', 'sticky')
|
||||||
} else {
|
} else {
|
||||||
toggleClass(body, 'remove', 'sticky')
|
dom.toggleClass(dom.body, 'remove', 'sticky')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAndActive (el, isParent) {
|
/**
|
||||||
const dom = getNode(el)
|
* Get and active link
|
||||||
const links = findAll(dom, 'a')
|
* @param {string|element} el
|
||||||
const hash = '#' + getHash()
|
* @param {Boolean} isParent acitve parent
|
||||||
|
* @param {Boolean} autoTitle auto set title
|
||||||
|
* @return {element}
|
||||||
|
*/
|
||||||
|
export function getAndActive (el, isParent, autoTitle) {
|
||||||
|
el = dom.getNode(el)
|
||||||
|
|
||||||
|
const links = dom.findAll(el, 'a')
|
||||||
|
const hash = '#' + getHash()
|
||||||
let target
|
let target
|
||||||
|
|
||||||
links
|
links
|
||||||
|
|
@ -48,11 +56,15 @@ export function getAndActive (el, isParent) {
|
||||||
|
|
||||||
if (hash.indexOf(href) === 0 && !target) {
|
if (hash.indexOf(href) === 0 && !target) {
|
||||||
target = a
|
target = a
|
||||||
toggleClass(node, 'add', 'active')
|
dom.toggleClass(node, 'add', 'active')
|
||||||
} else {
|
} else {
|
||||||
toggleClass(node, 'remove', 'active')
|
dom.toggleClass(node, 'remove', 'active')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (autoTitle) {
|
||||||
|
dom.$.title = target ? `${target.innerText} - ${title}` : title
|
||||||
|
}
|
||||||
|
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,7 @@ renderer.code = function (code, lang = '') {
|
||||||
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
return `<pre v-pre data-lang="${lang}"><code class="lang-${lang}">${hl}</code></pre>`
|
||||||
}
|
}
|
||||||
renderer.link = function (href, title, text) {
|
renderer.link = function (href, title, text) {
|
||||||
if (!/:|(\/{2})/.test(href)) {
|
return `<a href="${toURL(href)}" title="${title || text}">${text}</a>`
|
||||||
href = toURL(href)
|
|
||||||
}
|
|
||||||
return `<a href="${href}" title="${title || ''}">${text}</a>`
|
|
||||||
}
|
}
|
||||||
renderer.paragraph = function (text) {
|
renderer.paragraph = function (text) {
|
||||||
if (/^!>/.test(text)) {
|
if (/^!>/.test(text)) {
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,22 @@ export function renderMixin (proto) {
|
||||||
}
|
}
|
||||||
|
|
||||||
proto._renderSidebar = function (text) {
|
proto._renderSidebar = function (text) {
|
||||||
const { maxLevel, subMaxLevel } = this.config
|
const { maxLevel, subMaxLevel, autoHeader } = this.config
|
||||||
|
|
||||||
this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
|
this._renderTo('.sidebar-nav', sidebar(text, maxLevel))
|
||||||
subSidebar(getAndActive('.sidebar-nav', true), subMaxLevel)
|
const active = getAndActive('.sidebar-nav', true, true)
|
||||||
|
subSidebar(active, subMaxLevel)
|
||||||
// bind event
|
// bind event
|
||||||
scrollActiveSidebar()
|
scrollActiveSidebar()
|
||||||
|
|
||||||
|
if (autoHeader && active) {
|
||||||
|
const main = dom.getNode('#main')
|
||||||
|
if (main.children[0].tagName !== 'H1') {
|
||||||
|
const h1 = dom.create('h1')
|
||||||
|
h1.innerText = active.innerText
|
||||||
|
dom.before(main, h1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proto._renderNav = function (text) {
|
proto._renderNav = function (text) {
|
||||||
|
|
@ -128,7 +138,7 @@ export function initRender (vm) {
|
||||||
// Render main app
|
// Render main app
|
||||||
vm._renderTo(el, html, true)
|
vm._renderTo(el, html, true)
|
||||||
// Add nav
|
// Add nav
|
||||||
dom.body.insertBefore(navEl, dom.body.children[0])
|
dom.before(dom.body, navEl)
|
||||||
|
|
||||||
if (config.themeColor) {
|
if (config.themeColor) {
|
||||||
dom.$.head += tpl.theme(config.themeColor)
|
dom.$.head += tpl.theme(config.themeColor)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { merge, cached } from '../util/core'
|
import { merge, cached } from '../util/core'
|
||||||
import { parseQuery, stringifyQuery } from './util'
|
import { parseQuery, stringifyQuery, cleanPath } from './util'
|
||||||
|
|
||||||
function replaceHash (path) {
|
function replaceHash (path) {
|
||||||
const i = window.location.href.indexOf('#')
|
const i = window.location.href.indexOf('#')
|
||||||
|
|
@ -70,5 +70,5 @@ export function toURL (path, params) {
|
||||||
route.query = merge({}, route.query, params)
|
route.query = merge({}, route.query, params)
|
||||||
path = route.path + stringifyQuery(route.query)
|
path = route.path + stringifyQuery(route.query)
|
||||||
|
|
||||||
return '#' + path
|
return cleanPath('#/' + path)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,10 @@ export function appendTo (target, el) {
|
||||||
return target.appendChild(el)
|
return target.appendChild(el)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function before (target, el) {
|
||||||
|
return target.insertBefore(el, target.children[0])
|
||||||
|
}
|
||||||
|
|
||||||
export function on (el, type, handler) {
|
export function on (el, type, handler) {
|
||||||
isFn(type)
|
isFn(type)
|
||||||
? window.addEventListener(el, type)
|
? window.addEventListener(el, type)
|
||||||
|
|
@ -72,5 +76,5 @@ export const off = function on (el, type, handler) {
|
||||||
* toggleClass(el, 'add', 'active') => el.classList.add('active')
|
* toggleClass(el, 'add', 'active') => el.classList.add('active')
|
||||||
*/
|
*/
|
||||||
export function toggleClass (el, type, val) {
|
export function toggleClass (el, type, val) {
|
||||||
el.classList[val ? type : 'toggle'](val || type)
|
el && el.classList[val ? type : 'toggle'](val || type)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue