themes/ehc/static/js/theme.js
94 Zeilen · 3.3 KB · JavaScript
| 1 | (function() { |
| 2 | var html = document.documentElement; |
| 3 | var toggle = document.getElementById('theme-toggle'); |
| 4 | var stored = localStorage.getItem('theme'); |
| 5 | |
| 6 | if (stored) { |
| 7 | html.setAttribute('data-theme', stored); |
| 8 | } |
| 9 | |
| 10 | function updateIcon() { |
| 11 | if (toggle) { |
| 12 | toggle.textContent = html.getAttribute('data-theme') === 'dark' ? '\u263D' : '\u2600\uFE0F'; |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | updateIcon(); |
| 17 | |
| 18 | if (toggle) { |
| 19 | toggle.addEventListener('click', function() { |
| 20 | var next = html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'; |
| 21 | html.setAttribute('data-theme', next); |
| 22 | localStorage.setItem('theme', next); |
| 23 | updateIcon(); |
| 24 | }); |
| 25 | } |
| 26 | |
| 27 | // Hamburger menu |
| 28 | var hamburger = document.getElementById('hamburger'); |
| 29 | var navLinks = document.getElementById('nav-links'); |
| 30 | if (hamburger && navLinks) { |
| 31 | hamburger.addEventListener('click', function() { |
| 32 | hamburger.classList.toggle('active'); |
| 33 | navLinks.classList.toggle('open'); |
| 34 | }); |
| 35 | // Close mobile menu when clicking a link |
| 36 | navLinks.querySelectorAll('a').forEach(function(link) { |
| 37 | link.addEventListener('click', function() { |
| 38 | hamburger.classList.remove('active'); |
| 39 | navLinks.classList.remove('open'); |
| 40 | }); |
| 41 | }); |
| 42 | } |
| 43 | |
| 44 | // Dropdown toggles (for mobile tap support) |
| 45 | document.querySelectorAll('.nav-dropdown-toggle').forEach(function(btn) { |
| 46 | btn.addEventListener('click', function(e) { |
| 47 | e.preventDefault(); |
| 48 | e.stopPropagation(); |
| 49 | var dropdown = btn.closest('.nav-dropdown'); |
| 50 | // Close other dropdowns |
| 51 | document.querySelectorAll('.nav-dropdown.open').forEach(function(other) { |
| 52 | if (other !== dropdown) other.classList.remove('open'); |
| 53 | }); |
| 54 | dropdown.classList.toggle('open'); |
| 55 | }); |
| 56 | }); |
| 57 | |
| 58 | // Close dropdown when clicking outside |
| 59 | document.addEventListener('click', function(e) { |
| 60 | if (!e.target.closest('.nav-dropdown')) { |
| 61 | document.querySelectorAll('.nav-dropdown.open').forEach(function(d) { |
| 62 | d.classList.remove('open'); |
| 63 | }); |
| 64 | } |
| 65 | }); |
| 66 | |
| 67 | // TOC generator for posts with toc: true |
| 68 | var toc = document.getElementById('toc'); |
| 69 | if (toc) { |
| 70 | var headings = document.querySelectorAll('.post-content h1, .post-content h2, .post-content h3'); |
| 71 | if (headings.length > 0) { |
| 72 | // Determine the highest (smallest number) heading level used |
| 73 | var minLevel = 6; |
| 74 | headings.forEach(function(h) { |
| 75 | var level = parseInt(h.tagName.charAt(1)); |
| 76 | if (level < minLevel) minLevel = level; |
| 77 | }); |
| 78 | |
| 79 | var ul = document.createElement('ul'); |
| 80 | headings.forEach(function(h) { |
| 81 | var level = parseInt(h.tagName.charAt(1)); |
| 82 | var li = document.createElement('li'); |
| 83 | // Indent relative to the highest heading level found |
| 84 | li.className = 'toc-level-' + (level - minLevel); |
| 85 | var a = document.createElement('a'); |
| 86 | a.href = '#' + h.id; |
| 87 | a.textContent = h.textContent; |
| 88 | li.appendChild(a); |
| 89 | ul.appendChild(li); |
| 90 | }); |
| 91 | toc.appendChild(ul); |
| 92 | } |
| 93 | } |
| 94 | })(); |