'use strict'; // // script.js - script which handles: // // - check/set dark mode (added 2024-05-27) // - enable burger menu support // // original notes regarding burger menu and minification are in the // "burger menu" section below // // burker menu (2024-05-27) // ------------------------ // does the following: // // 1. checks for user setting and use that, if present. // 2. otherwise check browser for preferred color scheme and use that. // // this works in conjunction with the styles in `assets/dark.sass` and // has one minor quirk: there is a brief flash when the user transitions // to a new page and has dark mode enabled. this can be removed by // uncommenting the block at the top of `dark.sass`, but doing this // currently breaks the light color scheme :/. // // refs: // https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme // https://www.smashingmagazine.com/2024/03/setting-persisting-color-scheme-preferences-css-javascript/ // https://css-tricks.com/approaches-media-queries-sass/ // https://stackoverflow.com/questions/59621784/how-to-detect-prefers-color-scheme-change-in-javascript // // burker menu // ----------- // src: https://bulma.io/documentation/components/navbar/ // // Note (2022-03-05): I initially switched from Array.prototype.slice() // to Array.from() and added "const D = document;" to shrink the // minified, uncompressed code from 307 bytes to 292 bytes for a ~4.9% // (15 bytes) size reduction. // // Then, I dropped Array.from() entirely, since all modern browsers (see // URL below) support NodeList.forEach(). // // Ref: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach // // This shrunk the minified, uncompressed size to 280 bytes, for a // ~8.8% (27 bytes) cumulative size reduction. // // I also tried switching from forEach to for..of, but that increased // the minified, uncompressed size by a two bytes. // // aliases const D = document, C = D.body.parentElement.classList, L = localStorage, M = window.matchMedia, on = (el, id, fn) => el.addEventListener(id, fn); // use theme if set, otherwise fall back to browser preference // FIXME: move to DOMContentLoaded? if (L && L.theme && L.theme === 'dark') { C.add('dark'); // theme set to "dark" } else if ((!L || !L.theme) && M && M('(prefers-color-scheme: dark)').matches) { C.add('dark'); // prefers dark color scheme } document.addEventListener('DOMContentLoaded', () => { // theme toggle event handler on(D.querySelector('.navbar-item[data-id="theme"]'), 'click', (e) => { e.preventDefault(); // stop event L.theme = C.toggle('dark') ? 'dark' : 'light'; // toggle }); // iterate through burgers, bind to click events D.querySelectorAll('.navbar-burger').forEach(e => on(e, 'click', () => { // then toggle is-active on burger and menu [e, D.getElementById(e.dataset.target)].forEach( e => e.classList.toggle('is-active') ) })); });