add JavaScript for navigation menu
authorDan Allen <dan@opendevise.com>
Sat, 18 Nov 2017 03:10:27 +0000 (20:10 -0700)
committerDan Allen <dan@opendevise.com>
Sun, 19 Nov 2017 03:41:34 +0000 (20:41 -0700)
src/css/navigation-domain.css
src/js/01-navigation.js [new file with mode: 0644]
src/partials/footer-scripts.hbs

index 9d7b10a..9168177 100644 (file)
@@ -27,6 +27,7 @@ html.is-clipped--nav {
   list-style: none;
   margin: 0;
   padding: 0;
+  width: 100%;
 }
 
 .nav-list .nav-list {
diff --git a/src/js/01-navigation.js b/src/js/01-navigation.js
new file mode 100644 (file)
index 0000000..df8d00f
--- /dev/null
@@ -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))
+  }
+})()
index 385a43b..9e9f561 100644 (file)
@@ -1,2 +1,3 @@
+<script src="{{or uiRootPath themeRootPath}}/js/site.js"></script>
 <script src="{{or uiRootPath themeRootPath}}/js/vendor/highlight.js"></script>
 <script>hljs.initHighlighting()</script>