1/** Off-canvas menu open/close (no Bricks/jQuery). */ 2(function () { 3 function init() { 4 var panel = document.querySelector('[data-nav-panel]'); 5 var openBtn = document.querySelector('[data-nav-open]'); 6 if (!panel || !openBtn) return; 7 8 var closers = panel.querySelectorAll('[data-nav-close]'); 9 var scroller = panel.querySelector('.jbw-menu__panel') || panel; 10 var jumps = panel.querySelectorAll('[data-nav-scroll]'); 11 12 function open() { 13 panel.hidden = false; 14 // Force reflow so the transition runs from the hidden state. 15 void panel.offsetWidth; 16 panel.classList.add('is-open'); 17 document.body.classList.add('menu-open'); 18 openBtn.setAttribute('aria-expanded', 'true'); 19 scroller.scrollTop = 0; 20 } 21 22 function close() { 23 panel.classList.remove('is-open'); 24 document.body.classList.remove('menu-open'); 25 openBtn.setAttribute('aria-expanded', 'false'); 26 setTimeout(function () { 27 panel.hidden = true; 28 }, 500); 29 } 30 31 function scrollToSection(id) { 32 var target = document.getElementById(id); 33 if (!target || !scroller.contains(target)) return; 34 35 var scrollerRect = scroller.getBoundingClientRect(); 36 var targetRect = target.getBoundingClientRect(); 37 var nextTop = scroller.scrollTop + (targetRect.top - scrollerRect.top); 38 39 if (typeof scroller.scrollTo === 'function') { 40 scroller.scrollTo({ top: nextTop, behavior: 'smooth' }); 41 } else { 42 scroller.scrollTop = nextTop; 43 } 44 } 45 46 openBtn.addEventListener('click', open); 47 closers.forEach(function (el) { 48 el.addEventListener('click', close); 49 }); 50 jumps.forEach(function (btn) { 51 btn.addEventListener('click', function () { 52 scrollToSection(btn.getAttribute('data-nav-scroll')); 53 }); 54 }); 55 document.addEventListener('keydown', function (e) { 56 if (e.key === 'Escape' && panel.classList.contains('is-open')) close(); 57 }); 58 } 59 60 if (document.readyState === 'loading') { 61 document.addEventListener('DOMContentLoaded', init); 62 } else { 63 init(); 64 } 65})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.