summaryrefslogtreecommitdiffstats
path: root/src/js
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2017-11-20 23:39:31 +0000
committerDan Allen <dan.j.allen@gmail.com>2017-11-20 23:39:31 +0000
commit9282be7bf52ae46b80fa6163cbc1b65374ac619c (patch)
tree2c82806bb3fdbcca8e38ce8eab9a12a04cddda54 /src/js
parentec2092b985830c9c8877de14fa250bfda6eda42d (diff)
parentc6be6967c6236ddeabf37469dd850238095d5734 (diff)
downloadalpine-antora-theme-9282be7bf52ae46b80fa6163cbc1b65374ac619c.tar.bz2
alpine-antora-theme-9282be7bf52ae46b80fa6163cbc1b65374ac619c.tar.xz
merge !10
resolves #10 add JavaScript for navigation menu
Diffstat (limited to 'src/js')
-rw-r--r--src/js/01-navigation.js122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/js/01-navigation.js b/src/js/01-navigation.js
new file mode 100644
index 0000000..df8d00f
--- /dev/null
+++ b/src/js/01-navigation.js
@@ -0,0 +1,122 @@
+;(function () {
+ 'use strict'
+
+ var navContainer = document.querySelector('.navigation-container')
+ var navToggle = document.querySelector('.navigation-toggle')
+ var domainNav = navContainer.querySelector('[data-panel=domain]')
+ var state = getState() || {}
+
+ navContainer.querySelector('.current').addEventListener('click', function () {
+ var currentPanel = document.querySelector('.navigation .is-active[data-panel]')
+ var selectPanel = currentPanel.dataset.panel === 'domain' ? 'explore' : 'domain'
+ currentPanel.classList.toggle('is-active')
+ document.querySelector('.navigation [data-panel=' + selectPanel + ']').classList.toggle('is-active')
+ })
+
+ navToggle.addEventListener('click', toggleNavigation)
+ // don't let click events propagate outside of navigation container
+ navContainer.addEventListener('click', concealEvent)
+
+ find('.nav-menu').forEach(function (navTree) {
+ var panel = navTree.parentElement.dataset.panel
+ find('.nav-item', navTree).forEach(function (item, idx) {
+ item.setAttribute('data-id', [panel, item.dataset.depth, idx].join('-'))
+ })
+ })
+
+ find('.nav-toggle').forEach(function (btn) {
+ var li = btn.parentElement
+ btn.addEventListener('click', function () {
+ li.classList.toggle('is-active')
+ state.expandedItems = getExpandedItems()
+ saveState()
+ })
+ })
+
+ if (!state.expandedItems) {
+ state.expandedItems = getExpandedItems()
+ saveState()
+ }
+
+ state.expandedItems.forEach(function (itemId) {
+ var item = document.querySelector('.nav-item[data-id="' + itemId + '"]')
+ if (item) {
+ item.classList.add('is-active')
+ }
+ })
+
+ saveState()
+
+ scrollItemIntoView(state.scroll || 0, domainNav, document.querySelector('.nav-menu .is-current-page .nav-link'))
+ domainNav.addEventListener('scroll', function () {
+ state.scroll = Math.round(domainNav.scrollTop)
+ saveState()
+ })
+
+ function toggleNavigation (e) {
+ if (navToggle.classList.contains('is-active')) {
+ return closeNavigation(e)
+ }
+ document.documentElement.classList.add('is-clipped--nav')
+ navToggle.classList.add('is-active')
+ navContainer.classList.add('is-active')
+ window.addEventListener('click', closeNavigation)
+ // don't let this event get picked up by window click listener
+ concealEvent(e)
+ }
+
+ function closeNavigation (e) {
+ if (e.which === 3 || e.button === 2) return
+ document.documentElement.classList.remove('is-clipped--nav')
+ navToggle.classList.remove('is-active')
+ navContainer.classList.remove('is-active')
+ window.removeEventListener('click', closeNavigation)
+ // don't let this event get picked up by window click listener
+ concealEvent(e)
+ }
+
+ function concealEvent (e) {
+ e.stopPropagation()
+ }
+
+ function getExpandedItems () {
+ return find('.nav-menu .is-active').map(function (item) {
+ return item.dataset.id
+ })
+ }
+
+ function getState (domain, version) {
+ var data = window.sessionStorage.getItem('nav-state')
+ if (data) {
+ return JSON.parse(data)
+ }
+ }
+
+ function saveState () {
+ window.sessionStorage.setItem('nav-state', JSON.stringify(state))
+ }
+
+ function scrollItemIntoView (scrollPosition, parent, el) {
+ if (el === null) {
+ return (parent.scrollTop = scrollPosition)
+ }
+
+ var margin = 10
+
+ var overTheTop = el.offsetTop - scrollPosition < 0
+ var belowTheBottom = el.offsetTop - scrollPosition + el.offsetHeight > parent.offsetHeight
+
+ if (overTheTop) {
+ parent.scrollTop = el.offsetTop - margin
+ } else if (belowTheBottom) {
+ parent.scrollTop = el.offsetTop - (parent.offsetHeight - el.offsetHeight) + margin
+ } else {
+ parent.scrollTop = scrollPosition
+ }
+ }
+
+ function find (selector, from) {
+ from = from || document
+ return [].slice.call(from.querySelectorAll(selector))
+ }
+})()