mirror of
https://github.com/wahyd4/links.git
synced 2026-08-08 21:04:53 +10:00
120 lines
4.4 KiB
JavaScript
120 lines
4.4 KiB
JavaScript
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
const moreMenuButton = document.getElementById('more-menu-button');
|
|
const moreMenuDropdown = document.getElementById('more-menu-dropdown');
|
|
const languageSelectorButton = document.getElementById('language-selector-button');
|
|
const languageOptions = document.getElementById('language-options');
|
|
|
|
const isMobile = () => window.innerWidth < 768; // matches Tailwind's md breakpoint
|
|
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
const ANIM_MS = reduceMotion ? 0 : 320;
|
|
|
|
function isOpen(dropdown) {
|
|
return dropdown ? dropdown.classList.contains('menu-open') : false;
|
|
}
|
|
|
|
function openDropdown(dropdown) {
|
|
dropdown.classList.add('menu-open');
|
|
if (isMobile()) {
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
}
|
|
|
|
function closeDropdown(dropdown) {
|
|
dropdown.classList.remove('menu-open');
|
|
if (isMobile()) {
|
|
// Release body scroll only after the slide-up animation finishes
|
|
setTimeout(() => {
|
|
if (!isOpen(moreMenuDropdown) && !isOpen(languageOptions)) {
|
|
document.body.style.overflow = '';
|
|
}
|
|
}, ANIM_MS);
|
|
}
|
|
}
|
|
|
|
function toggleDropdown(button, dropdown) {
|
|
button.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (!isOpen(dropdown)) {
|
|
// Close other dropdown first
|
|
if (dropdown === moreMenuDropdown && isOpen(languageOptions)) {
|
|
closeDropdown(languageOptions);
|
|
}
|
|
if (dropdown === languageOptions && isOpen(moreMenuDropdown)) {
|
|
closeDropdown(moreMenuDropdown);
|
|
}
|
|
openDropdown(dropdown);
|
|
} else {
|
|
closeDropdown(dropdown);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (moreMenuButton && moreMenuDropdown) {
|
|
toggleDropdown(moreMenuButton, moreMenuDropdown);
|
|
|
|
// Close dropdown when a menu link is clicked (mobile: auto-dismiss on navigate)
|
|
moreMenuDropdown.querySelectorAll('a').forEach(link => {
|
|
link.addEventListener('click', function() {
|
|
closeDropdown(moreMenuDropdown);
|
|
});
|
|
});
|
|
}
|
|
|
|
if (languageSelectorButton && languageOptions) {
|
|
toggleDropdown(languageSelectorButton, languageOptions);
|
|
}
|
|
|
|
// Close dropdowns when clicking outside
|
|
document.addEventListener('click', function(e) {
|
|
if (moreMenuDropdown && !moreMenuButton.contains(e.target) && !moreMenuDropdown.contains(e.target)) {
|
|
if (isOpen(moreMenuDropdown)) closeDropdown(moreMenuDropdown);
|
|
}
|
|
if (languageOptions && !languageSelectorButton.contains(e.target) && !languageOptions.contains(e.target)) {
|
|
if (isOpen(languageOptions)) closeDropdown(languageOptions);
|
|
}
|
|
});
|
|
|
|
// Close dropdowns on Escape key
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
if (isOpen(moreMenuDropdown)) closeDropdown(moreMenuDropdown);
|
|
if (isOpen(languageOptions)) closeDropdown(languageOptions);
|
|
}
|
|
});
|
|
|
|
// Handle window resize: close mobile overlay if resizing to desktop
|
|
window.addEventListener('resize', function() {
|
|
if (!isMobile()) {
|
|
document.body.style.overflow = '';
|
|
}
|
|
});
|
|
|
|
// Language form submission
|
|
const languageForm = document.getElementById('language-form');
|
|
if (languageForm) {
|
|
const languageButtons = languageForm.querySelectorAll('button[name="language"]');
|
|
languageButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
languageForm.submit();
|
|
});
|
|
});
|
|
}
|
|
|
|
// Scroll-responsive navigation: hide on scroll down, show on scroll up
|
|
let lastScrollTop = 0;
|
|
const navbar = document.querySelector('nav');
|
|
|
|
if (navbar) {
|
|
window.addEventListener('scroll', function() {
|
|
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
if (scrollTop > lastScrollTop && scrollTop > 60) {
|
|
navbar.style.top = '-80px';
|
|
} else {
|
|
navbar.style.top = '0';
|
|
}
|
|
lastScrollTop = scrollTop;
|
|
});
|
|
}
|
|
}); |