* feat: custom sidebar, #4 * fix dev html * fix doc * fix doc
This commit is contained in:
parent
fc2e5b6fb9
commit
37e7984e7e
6 changed files with 71 additions and 15 deletions
|
|
@ -121,3 +121,26 @@ Root element.
|
||||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### sidebar
|
||||||
|
|
||||||
|
Custom sidebar. if it'set, the TOC will be disabeld. Bind global variables on the `data-sidebar`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
window.sidebar = [
|
||||||
|
{ slug: '/', title: 'Home' },
|
||||||
|
{
|
||||||
|
slug: '/pageA',
|
||||||
|
title: 'page A',
|
||||||
|
children: [
|
||||||
|
{ slug: '/pageA/childrenB', title: 'children B' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ slug: '/PageC', title: 'Page C' }
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,4 +119,26 @@ docsify serve docs
|
||||||
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
<script src="//unpkg.com/docsify" data-el="#app"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### sidebar
|
||||||
|
|
||||||
|
设置后 TOC 功能将不可用,适合导航较多的文档,`data-sidebar` 传入全局变量名。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```html
|
||||||
|
<script>
|
||||||
|
window.sidebar = [
|
||||||
|
{ slug: '/', title: 'Home' },
|
||||||
|
{
|
||||||
|
slug: '/pageA',
|
||||||
|
title: 'page A',
|
||||||
|
children: [
|
||||||
|
{ slug: '/pageA/childrenB', title: 'children B' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ slug: '/PageC', title: 'Page C' }
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
function scrollActiveSidebar () {
|
function scrollActiveSidebar (isCustom) {
|
||||||
if (/mobile/i.test(navigator.userAgent)) return
|
if (/mobile/i.test(navigator.userAgent) || isCustom) return
|
||||||
|
|
||||||
const anchors = document.querySelectorAll('.anchor')
|
const anchors = document.querySelectorAll('.anchor')
|
||||||
const nav = {}
|
const nav = {}
|
||||||
|
|
@ -48,6 +48,6 @@ function scrollActiveSidebar () {
|
||||||
scrollIntoView()
|
scrollIntoView()
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function () {
|
export default function (isCustom) {
|
||||||
scrollActiveSidebar()
|
scrollActiveSidebar(isCustom)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ const tocToTree = function (toc, maxLevel) {
|
||||||
const buildHeadlinesTree = function (tree, tpl = '') {
|
const buildHeadlinesTree = function (tree, tpl = '') {
|
||||||
if (!tree || !tree.length) return ''
|
if (!tree || !tree.length) return ''
|
||||||
|
|
||||||
tree.forEach((node) => {
|
tree.forEach(node => {
|
||||||
tpl += `<li><a class="section-link" href="#${node.slug}">${node.title}</a></li>`
|
tpl += `<li><a class="section-link" href="${node.slug}">${node.title}</a></li>`
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
tpl += `<li><ul class="children">${buildHeadlinesTree(node.children)}</li></ul>`
|
tpl += `<li><ul class="children">${buildHeadlinesTree(node.children)}</li></ul>`
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,10 @@ const buildHeadlinesTree = function (tree, tpl = '') {
|
||||||
return tpl
|
return tpl
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (toc, maxLevel) {
|
export default function (toc, opts) {
|
||||||
var tree = tocToTree(toc, maxLevel)
|
var tree = Array.isArray(opts.sidebar)
|
||||||
|
? opts.sidebar
|
||||||
|
: tocToTree(toc, opts['max-level'])
|
||||||
|
|
||||||
return buildHeadlinesTree(tree, '<ul>')
|
return buildHeadlinesTree(tree, '<ul>')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/index.js
18
src/index.js
|
|
@ -5,7 +5,8 @@ import bindEvent from './bind-event'
|
||||||
const DEFAULT_OPTS = {
|
const DEFAULT_OPTS = {
|
||||||
el: '#app',
|
el: '#app',
|
||||||
repo: '',
|
repo: '',
|
||||||
'max-level': 6
|
'max-level': 6,
|
||||||
|
sidebar: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
|
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
|
||||||
|
|
@ -21,15 +22,17 @@ class Docsify {
|
||||||
Docsify.installed = true
|
Docsify.installed = true
|
||||||
|
|
||||||
this.opts = Object.assign({}, opts, DEFAULT_OPTS)
|
this.opts = Object.assign({}, opts, DEFAULT_OPTS)
|
||||||
|
|
||||||
this.replace = true
|
this.replace = true
|
||||||
this.dom = document.querySelector(this.opts.el)
|
this.dom = document.querySelector(this.opts.el)
|
||||||
if (!this.dom) {
|
if (!this.dom) {
|
||||||
this.dom = document.body
|
this.dom = document.body
|
||||||
this.replace = false
|
this.replace = false
|
||||||
}
|
}
|
||||||
|
if (this.opts.sidebar) this.opts.sidebar = window[this.opts.sidebar]
|
||||||
|
|
||||||
this.loc = document.location.pathname
|
this.loc = document.location.pathname
|
||||||
if (/\/$/.test(this.loc)) this.loc += 'README'
|
if (/\/$/.test(this.loc)) this.loc += 'README'
|
||||||
|
|
||||||
this.load()
|
this.load()
|
||||||
|
|
||||||
const nav = document.querySelector('nav')
|
const nav = document.querySelector('nav')
|
||||||
|
|
@ -43,7 +46,10 @@ class Docsify {
|
||||||
this.render('not found')
|
this.render('not found')
|
||||||
} else {
|
} else {
|
||||||
this.render(res.target.response)
|
this.render(res.target.response)
|
||||||
bindEvent()
|
bindEvent(!!this.opts.sidebar)
|
||||||
|
if (this.opts.sidebar) {
|
||||||
|
this.activeNav(document.querySelector('aside.sidebar'), true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -52,12 +58,14 @@ class Docsify {
|
||||||
this.dom[this.replace ? 'outerHTML' : 'innerHTML'] = render(content, this.opts)
|
this.dom[this.replace ? 'outerHTML' : 'innerHTML'] = render(content, this.opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
activeNav (elm) {
|
activeNav (elm, activeParentNode) {
|
||||||
const host = document.location.origin + document.location.pathname
|
const host = document.location.origin + document.location.pathname
|
||||||
|
|
||||||
;[].slice.call(elm.querySelectorAll('a')).forEach(node => {
|
;[].slice.call(elm.querySelectorAll('a')).forEach(node => {
|
||||||
if (node.href === host) {
|
if (node.href === host) {
|
||||||
node.setAttribute('class', 'active')
|
activeParentNode
|
||||||
|
? node.parentNode.setAttribute('class', 'active')
|
||||||
|
: node.setAttribute('class', 'active')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const renderer = new marked.Renderer()
|
||||||
renderer.heading = function (text, level) {
|
renderer.heading = function (text, level) {
|
||||||
const slug = text.replace(/<(?:.|\n)*?>/gm, '').toLowerCase().replace(/[\s\n\t]+/g, '-')
|
const slug = text.replace(/<(?:.|\n)*?>/gm, '').toLowerCase().replace(/[\s\n\t]+/g, '-')
|
||||||
|
|
||||||
toc.push({ level, slug, title: text })
|
toc.push({ level, slug: '#' + slug, title: text })
|
||||||
|
|
||||||
return `<h${level} id="${slug}"><a href="#${slug}" class="anchor"></a>${text}</h${level}>`
|
return `<h${level} id="${slug}"><a href="#${slug}" class="anchor"></a>${text}</h${level}>`
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ export default function (content, opts = {}) {
|
||||||
const section = `<section class="content">
|
const section = `<section class="content">
|
||||||
<article class="markdown-section">${marked(content)}</article>
|
<article class="markdown-section">${marked(content)}</article>
|
||||||
</section>`
|
</section>`
|
||||||
const sidebar = `<aside class="sidebar">${genToc(toc, opts['max-level'])}</aside>`
|
const sidebar = `<aside class="sidebar">${genToc(toc, opts)}</aside>`
|
||||||
|
|
||||||
return `${corner}<main>${sidebar}${section}</main>`
|
return `${corner}<main>${sidebar}${section}</main>`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue