philomena/assets/js/burger.ts

73 lines
2 KiB
TypeScript
Raw Normal View History

2019-10-05 02:09:52 +02:00
/**
* Hamburger menu.
*/
import { $, $$ } from './utils/dom';
import { assertNotNull } from './utils/assert';
function switchClasses(element: HTMLElement, oldClass: string, newClass: string) {
2019-10-05 02:09:52 +02:00
element.classList.remove(oldClass);
element.classList.add(newClass);
}
function open(burger: HTMLElement, content: HTMLElement, body: HTMLElement, root: HTMLElement) {
2019-10-05 02:09:52 +02:00
switchClasses(content, 'close', 'open');
switchClasses(burger, 'close', 'open');
root.classList.add('no-overflow-x');
body.classList.add('no-overflow');
}
function close(burger: HTMLElement, content: HTMLElement, body: HTMLElement, root: HTMLElement) {
2019-10-05 02:09:52 +02:00
switchClasses(content, 'open', 'close');
switchClasses(burger, 'open', 'close');
/* the CSS animation closing the menu finishes in 300ms */
setTimeout(() => {
root.classList.remove('no-overflow-x');
body.classList.remove('no-overflow');
}, 300);
}
2024-06-23 17:31:10 +02:00
function copyUserLinksTo(burger: HTMLElement) {
const copy = (links: HTMLCollection) => {
2019-10-05 02:09:52 +02:00
burger.appendChild(document.createElement('hr'));
for (const link of links) {
const burgerLink = link.cloneNode(true) as HTMLElement;
2019-10-05 02:09:52 +02:00
burgerLink.className = '';
burger.appendChild(burgerLink);
}
2019-10-05 02:09:52 +02:00
};
$$<HTMLElement>('.js-burger-links').forEach(container => copy(container.children));
2019-10-05 02:09:52 +02:00
}
export function setupBurgerMenu() {
// Burger menu should exist on all pages.
const burger = assertNotNull($<HTMLElement>('#burger'));
const toggle = assertNotNull($<HTMLElement>('#js-burger-toggle'));
const content = assertNotNull($<HTMLElement>('#container'));
2019-10-05 02:09:52 +02:00
const body = document.body;
const root = document.documentElement;
2024-06-23 17:31:10 +02:00
copyUserLinksTo(burger);
2019-10-05 02:09:52 +02:00
toggle.addEventListener('click', event => {
event.stopPropagation();
event.preventDefault();
if (content.classList.contains('open')) {
close(burger, content, body, root);
2024-07-04 02:27:59 +02:00
} else {
2019-10-05 02:09:52 +02:00
open(burger, content, body, root);
}
});
2019-10-05 02:09:52 +02:00
content.addEventListener('click', () => {
if (content.classList.contains('open')) {
close(burger, content, body, root);
}
});
}