Skip to content

Commit 37e7984

Browse files
authored
feat: custom sidebar, #4 (#5)
* feat: custom sidebar, #4 * fix dev html * fix doc * fix doc
1 parent fc2e5b6 commit 37e7984

File tree

6 files changed

+71
-15
lines changed

6 files changed

+71
-15
lines changed

docs/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,26 @@ Root element.
121121
<script src="//unpkg.com/docsify" data-el="#app"></script>
122122
```
123123

124+
#### sidebar
125+
126+
Custom sidebar. if it'set, the TOC will be disabeld. Bind global variables on the `data-sidebar`.
127+
128+
![image](https://cloud.githubusercontent.com/assets/7565692/20647425/de5ab1c2-b4ce-11e6-863a-135868f2f9b4.png)
129+
130+
```html
131+
<script>
132+
window.sidebar = [
133+
{ slug: '/', title: 'Home' },
134+
{
135+
slug: '/pageA',
136+
title: 'page A',
137+
children: [
138+
{ slug: '/pageA/childrenB', title: 'children B' }
139+
]
140+
},
141+
{ slug: '/PageC', title: 'Page C' }
142+
]
143+
</script>
144+
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
145+
```
146+

docs/zh-cn.md

+22
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,26 @@ docsify serve docs
119119
<script src="//unpkg.com/docsify" data-el="#app"></script>
120120
```
121121

122+
#### sidebar
123+
124+
设置后 TOC 功能将不可用,适合导航较多的文档,`data-sidebar` 传入全局变量名。
125+
126+
![image](https://cloud.githubusercontent.com/assets/7565692/20647425/de5ab1c2-b4ce-11e6-863a-135868f2f9b4.png)
127+
128+
```html
129+
<script>
130+
window.sidebar = [
131+
{ slug: '/', title: 'Home' },
132+
{
133+
slug: '/pageA',
134+
title: 'page A',
135+
children: [
136+
{ slug: '/pageA/childrenB', title: 'children B' }
137+
]
138+
},
139+
{ slug: '/PageC', title: 'Page C' }
140+
]
141+
</script>
142+
<script src="/lib/docsify.js" data-sidebar="sidebar"></script>
143+
```
122144

src/bind-event.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
function scrollActiveSidebar () {
2-
if (/mobile/i.test(navigator.userAgent)) return
1+
function scrollActiveSidebar (isCustom) {
2+
if (/mobile/i.test(navigator.userAgent) || isCustom) return
33

44
const anchors = document.querySelectorAll('.anchor')
55
const nav = {}
@@ -48,6 +48,6 @@ function scrollActiveSidebar () {
4848
scrollIntoView()
4949
}
5050

51-
export default function () {
52-
scrollActiveSidebar()
51+
export default function (isCustom) {
52+
scrollActiveSidebar(isCustom)
5353
}

src/gen-toc.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ const tocToTree = function (toc, maxLevel) {
2525
const buildHeadlinesTree = function (tree, tpl = '') {
2626
if (!tree || !tree.length) return ''
2727

28-
tree.forEach((node) => {
29-
tpl += `<li><a class="section-link" href="#${node.slug}">${node.title}</a></li>`
28+
tree.forEach(node => {
29+
tpl += `<li><a class="section-link" href="${node.slug}">${node.title}</a></li>`
3030
if (node.children) {
3131
tpl += `<li><ul class="children">${buildHeadlinesTree(node.children)}</li></ul>`
3232
}
@@ -35,7 +35,10 @@ const buildHeadlinesTree = function (tree, tpl = '') {
3535
return tpl
3636
}
3737

38-
export default function (toc, maxLevel) {
39-
var tree = tocToTree(toc, maxLevel)
38+
export default function (toc, opts) {
39+
var tree = Array.isArray(opts.sidebar)
40+
? opts.sidebar
41+
: tocToTree(toc, opts['max-level'])
42+
4043
return buildHeadlinesTree(tree, '<ul>')
4144
}

src/index.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import bindEvent from './bind-event'
55
const DEFAULT_OPTS = {
66
el: '#app',
77
repo: '',
8-
'max-level': 6
8+
'max-level': 6,
9+
sidebar: ''
910
}
1011

1112
const script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop()
@@ -21,15 +22,17 @@ class Docsify {
2122
Docsify.installed = true
2223

2324
this.opts = Object.assign({}, opts, DEFAULT_OPTS)
24-
2525
this.replace = true
2626
this.dom = document.querySelector(this.opts.el)
2727
if (!this.dom) {
2828
this.dom = document.body
2929
this.replace = false
3030
}
31+
if (this.opts.sidebar) this.opts.sidebar = window[this.opts.sidebar]
32+
3133
this.loc = document.location.pathname
3234
if (/\/$/.test(this.loc)) this.loc += 'README'
35+
3336
this.load()
3437

3538
const nav = document.querySelector('nav')
@@ -43,7 +46,10 @@ class Docsify {
4346
this.render('not found')
4447
} else {
4548
this.render(res.target.response)
46-
bindEvent()
49+
bindEvent(!!this.opts.sidebar)
50+
if (this.opts.sidebar) {
51+
this.activeNav(document.querySelector('aside.sidebar'), true)
52+
}
4753
}
4854
})
4955
}
@@ -52,12 +58,14 @@ class Docsify {
5258
this.dom[this.replace ? 'outerHTML' : 'innerHTML'] = render(content, this.opts)
5359
}
5460

55-
activeNav (elm) {
61+
activeNav (elm, activeParentNode) {
5662
const host = document.location.origin + document.location.pathname
5763

5864
;[].slice.call(elm.querySelectorAll('a')).forEach(node => {
5965
if (node.href === host) {
60-
node.setAttribute('class', 'active')
66+
activeParentNode
67+
? node.parentNode.setAttribute('class', 'active')
68+
: node.setAttribute('class', 'active')
6169
}
6270
})
6371
}

src/render.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const renderer = new marked.Renderer()
2121
renderer.heading = function (text, level) {
2222
const slug = text.replace(/<(?:.|\n)*?>/gm, '').toLowerCase().replace(/[\s\n\t]+/g, '-')
2323

24-
toc.push({ level, slug, title: text })
24+
toc.push({ level, slug: '#' + slug, title: text })
2525

2626
return `<h${level} id="${slug}"><a href="#${slug}" class="anchor"></a>${text}</h${level}>`
2727
}
@@ -45,7 +45,7 @@ export default function (content, opts = {}) {
4545
const section = `<section class="content">
4646
<article class="markdown-section">${marked(content)}</article>
4747
</section>`
48-
const sidebar = `<aside class="sidebar">${genToc(toc, opts['max-level'])}</aside>`
48+
const sidebar = `<aside class="sidebar">${genToc(toc, opts)}</aside>`
4949

5050
return `${corner}<main>${sidebar}${section}</main>`
5151
}

0 commit comments

Comments
 (0)