Skip to content

Commit 1db750e

Browse files
author
Evan You
committed
improve sidebars, WIP
1 parent 954b57d commit 1db750e

File tree

5 files changed

+148
-58
lines changed

5 files changed

+148
-58
lines changed

themes/vue/layout/layout.ejs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<script>
1111
window.PAGE_TYPE = "<%- page.type %>"
1212
</script>
13-
<script src="/js/vue.min.js"></script>
1413
<%- css(page.index ? 'css/index' : 'css/page') %>
1514
<%- partial('partials/ga') %>
15+
<script src="/js/vue.min.js"></script>
1616
</head>
1717
<body>
1818
<% if (page.index) { %>
@@ -27,6 +27,7 @@
2727
<%- body %>
2828
<% } %>
2929
</div>
30+
<script src="/js/smooth-scroll.min.js"></script>
3031
<script src="/js/common.js"></script>
3132
</body>
3233
</html>

themes/vue/layout/partials/sidebar.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="toggle">···</div>
33
<div class="list">
44
<h2><%- type.charAt(0).toUpperCase() + type.slice(1) %></h2>
5-
<ul>
5+
<ul class="menu-root">
66
<% site.pages.find({type: type}).sort('order').each(function (p) { %>
77
<li><a href="/<%- p.path %>" class="sidebar-link<%- page.title === p.title ? ' current' : '' %>"><%- p.title %></a></li>
88
<% }) %>

themes/vue/source/css/page.styl

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ $header-height = 40px
4444
position absolute
4545
top 0
4646
left 60px
47-
padding 2.2em 0 0 0
47+
bottom 0
48+
overflow-y scroll
49+
padding 2.2em 0
4850
width 260px
4951
margin-right 20px
52+
-webkit-overflow-scrolling touch
5053
.toggle
5154
font-size 1.5em
5255
cursor pointer
@@ -57,15 +60,23 @@ $header-height = 40px
5760
ul
5861
list-style-type none
5962
margin 0
60-
padding 0
61-
.sidebar-link
63+
padding-left 1em
6264
line-height 1.8em
65+
.menu-root
66+
padding-left 0
67+
.menu-sub
68+
font-size .85em
69+
.sidebar-link
6370
color $light
6471
&.current
6572
font-weight 600
6673
color $green
6774
&:hover
6875
border-bottom 2px solid $green
76+
.section-link
77+
&.active
78+
font-weight bold
79+
color $green
6980

7081
.content
7182
padding 2.2em 0
@@ -195,34 +206,24 @@ $header-height = 40px
195206
span
196207
display none
197208
#main
198-
padding 2em 1.4em 0
209+
padding 0 1.4em
199210
.highlight pre
200211
padding 1.2em 1em
201212
.sidebar
202-
position absolute
213+
position fixed
203214
background-color #fff
204215
z-index 10
205-
width 100%
216+
height 100%
206217
top 0
207218
left 0
208-
text-align center
209-
margin-right 0
210-
padding 0
211-
border-top 1px solid #eee
212-
box-shadow 0 2px 2px rgba(0,0,0,.1)
213-
.toggle
214-
display block
215-
.list
216-
display none
217-
.ad
218-
display none
219+
padding 20px 30px
220+
box-shadow 0 0 10px rgba(0,0,0,.2)
221+
box-sizing border-box
222+
transform translate(-110%,0)
223+
-webkit-transform translate(-110%,0)
219224
&.open
220-
padding-bottom 1em
221-
.list
222-
display block
223-
#main.fix-sidebar
224-
.sidebar
225-
position fixed
225+
transform translate(0,0)
226+
-webkit-transform translate(0,0)
226227
.content
227228
&.with-sidebar
228229
margin-left 0

themes/vue/source/js/common.js

Lines changed: 119 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,126 @@
11
(function () {
22

3-
var main = document.getElementById('main'),
4-
doc = document.documentElement,
5-
body = document.body,
6-
header = document.getElementById('header'),
7-
menu = document.querySelector('.sidebar'),
8-
menuToggle = document.querySelector('.sidebar .toggle')
9-
10-
if (menu) {
11-
window.addEventListener('scroll', function () {
12-
var top = doc && doc.scrollTop || body.scrollTop
13-
if (top > header.offsetHeight) {
14-
main.className = 'fix-sidebar'
15-
} else {
16-
main.className = ''
17-
}
18-
})
19-
menuToggle.addEventListener('click', function () {
20-
menu.classList.toggle('open')
21-
})
3+
var each = [].forEach
4+
var main = document.getElementById('main')
5+
var doc = document.documentElement
6+
var body = document.body
7+
var header = document.getElementById('header')
8+
var menu = document.querySelector('.sidebar')
9+
var menuToggle = document.querySelector('.sidebar .toggle')
10+
var content = document.querySelector('.content')
11+
12+
if (!menu) return
13+
14+
menuToggle.addEventListener('click', function () {
15+
menu.classList.toggle('open')
16+
})
17+
18+
// build sidebar
19+
var allLinks = []
20+
var currentPageAnchor = menu.querySelector('.sidebar-link.current')
21+
var sectionContainer = document.createElement('ul')
22+
sectionContainer.className = 'menu-sub'
23+
currentPageAnchor.parentNode.appendChild(sectionContainer)
24+
var h2s = content.querySelectorAll('h2')
25+
if (h2s.length) {
26+
each.call(h2s, function (h) {
27+
sectionContainer.appendChild(makeLink(h))
28+
var h3s = collectH3s(h)
29+
allLinks.push(h)
30+
allLinks.push.apply(allLinks, h3s)
31+
if (h3s.length) {
32+
sectionContainer.appendChild(makeSubLinks(h3s))
33+
}
34+
})
35+
} else {
36+
h2s = content.querySelectorAll('h3')
37+
each.call(h2s, function (h) {
38+
sectionContainer.appendChild(makeLink(h))
39+
allLinks.push(h)
40+
})
41+
}
42+
43+
// init smooth scroll
44+
smoothScroll.init({
45+
speed: 400
46+
})
47+
48+
var animating = false
49+
sectionContainer.addEventListener('click', function (e) {
50+
e.preventDefault()
51+
if (e.target.classList.contains('section-link')) {
52+
setActive(e.target)
53+
animating = true
54+
setTimeout(function () {
55+
animating = false
56+
}, 400)
2257
}
58+
}, true)
59+
60+
// listen for scroll event to do positioning & highlights
61+
window.addEventListener('scroll', updateSidebar)
62+
window.addEventListener('resize', updateSidebar)
63+
64+
function updateSidebar () {
65+
var top = doc && doc.scrollTop || body.scrollTop
66+
if (top > header.offsetHeight) {
67+
main.className = 'fix-sidebar'
68+
} else {
69+
main.className = ''
70+
}
71+
if (animating) return
72+
var last
73+
for (var i = 0; i < allLinks.length; i++) {
74+
var link = allLinks[i]
75+
if (link.offsetTop > top) {
76+
if (!last) last = link
77+
break
78+
} else {
79+
last = link
80+
}
81+
}
82+
if (last)
83+
setActive(last.id)
84+
}
85+
86+
function makeLink (h) {
87+
var link = document.createElement('li')
88+
link.innerHTML =
89+
'<a class="section-link" data-scroll href="#' + h.id + '">' +
90+
h.textContent.replace(/\(.*\)$/, '') +
91+
'</a>'
92+
return link
93+
}
94+
95+
function collectH3s (h) {
96+
var h3s = []
97+
var next = h.nextSibling
98+
while (next && next.tagName !== 'H2') {
99+
if (next.tagName === 'H3') {
100+
h3s.push(next)
101+
}
102+
next = next.nextSibling
103+
}
104+
return h3s
105+
}
106+
107+
function makeSubLinks (h3s) {
108+
var container = document.createElement('ul')
109+
h3s.forEach(function (h) {
110+
container.appendChild(makeLink(h))
111+
})
112+
return container
113+
}
23114

24-
if (PAGE_TYPE === 'api') {
25-
var h1 = document.querySelector('h1'),
26-
h3s = document.querySelectorAll('h3'),
27-
list = document.createElement('ul'),
28-
inner = '',
29-
replaceRE = /\(.*$/
30-
for (var i = 0, l = h3s.length; i < l; i++) {
31-
var h3 = h3s[i]
32-
inner += '<li><a href="#' + h3.id + '">' +
33-
h3.textContent.replace(replaceRE, '') +
34-
'</a></li>'
35-
}
36-
list.innerHTML = inner
37-
h1.parentNode.insertBefore(list, h1.nextSibling)
115+
function setActive (id) {
116+
var previousActive = menu.querySelector('.section-link.active')
117+
var currentActive = typeof id === 'string'
118+
? menu.querySelector('.section-link[href="#' + id + '"]')
119+
: id
120+
if (currentActive !== previousActive) {
121+
if (previousActive) previousActive.classList.remove('active')
122+
currentActive.classList.add('active')
38123
}
124+
}
39125

40126
})()

themes/vue/source/js/smooth-scroll.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)