Remove unused favicon.svg and enhance language dropdown initialization and event listener management

- Deleted the unused favicon.svg file to clean up the assets.
- Improved the LanguageDropdown component by preventing multiple initializations and ensuring proper cleanup of old event listeners to enhance performance and user experience.
- Updated BasicScripts to handle event listener removal more gracefully, preventing errors if elements are no longer in the DOM.
This commit is contained in:
2025-11-06 12:34:23 +01:00
parent 48f92017a9
commit 0299359a0f
3 changed files with 64 additions and 18 deletions

View File

@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" fill="none">
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
<path d="M64 20c12.5 0 22.3 4.6 28.9 13.3 5.6 7.2 8.3 16.7 7.4 26.3-1.6 17.6-16.7 28.2-30.2 28.2H57.9c-11.6 0-21.6-8.1-24.4-20.1C30.7 53.4 35.5 41 47.1 34.1 52.2 31 58.1 30 64 30v-10Zm0 12c-10.3 0-18.9 2.6-24.6 7.7-6.8 6-10.1 15.1-8.2 23.5C33.6 79.4 44.4 88 57.9 88h12.2c10.6 0 23.4-7.9 24.8-23.2.7-7.4-1.4-14.8-6.1-20.7C83.5 37.5 74.8 32 64 32v0Zm-6 36c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6Zm18 0c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6Zm-9 10c5 0 9 4 9 9s-4 9-9 9-9-4-9-9 4-9 9-9Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 706 B

View File

@@ -147,6 +147,15 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
</style>
<script define:vars={{ supportedLanguages }}>
// Prevent multiple initializations
if (window.languageDropdownInitialized) {
return;
}
window.languageDropdownInitialized = true;
// Store handlers for cleanup
const languageHandlers = new WeakMap();
function setupLanguageDropdown() {
const button = document.querySelector('#menu-button');
const menu = document.querySelector('#language-menu');
@@ -159,6 +168,24 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
return;
}
// Clean up old event listeners before adding new ones
const oldButtonHandler = languageHandlers.get(button);
if (oldButtonHandler) {
button.removeEventListener('click', oldButtonHandler);
}
const oldSelectHandler = languageHandlers.get(languageSelect);
if (oldSelectHandler) {
languageSelect.removeEventListener('change', oldSelectHandler);
}
languageButtons.forEach((langButton) => {
const oldHandler = languageHandlers.get(langButton);
if (oldHandler) {
langButton.removeEventListener('click', oldHandler);
}
});
let isOpen = false;
function closeMenu() {
@@ -207,7 +234,7 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
closeMenu();
// Toggle menu
button.addEventListener('click', (e) => {
const buttonHandler = (e) => {
e.stopPropagation();
if (isOpen) {
closeMenu();
@@ -215,11 +242,13 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
openMenu();
// Don't automatically focus any menu item to avoid default highlighting
}
});
};
button.addEventListener('click', buttonHandler);
languageHandlers.set(button, buttonHandler);
// Handle language selection
languageButtons.forEach((langButton) => {
langButton.addEventListener('click', () => {
const langButtonHandler = () => {
const langCode = langButton.dataset.langCode;
if (!langCode) return;
@@ -303,11 +332,14 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
// Force a complete page reload to ensure all content is updated to the new language
// This bypasses any client-side caching and ensures a fresh server render
window.location.href = newFullUrl + '?t=' + Date.now();
});
};
langButton.addEventListener('click', langButtonHandler);
languageHandlers.set(langButton, langButtonHandler);
});
// Handle language selection from select element
languageSelect.addEventListener('change', (event) => {
const selectHandler = (event) => {
const langCode = event.target.value;
if (!langCode) return;
@@ -377,7 +409,10 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
// Force a complete page reload to ensure all content is updated to the new language
// This bypasses any client-side caching and ensures a fresh server render
window.location.href = newFullUrl + '?t=' + Date.now();
});
};
languageSelect.addEventListener('change', selectHandler);
languageHandlers.set(languageSelect, selectHandler);
}
// Run setup when DOM is ready
@@ -388,7 +423,20 @@ const currentLanguage = languages.find((lang) => lang.code === currentLang) || l
}
// Re-run setup when the page content is updated (e.g., after navigation)
document.addEventListener('astro:page-load', setupLanguageDropdown);
document.addEventListener('astro:page-load', () => {
// Reset initialization flag to allow re-setup
window.languageDropdownInitialized = false;
setupLanguageDropdown();
window.languageDropdownInitialized = true;
});
// Re-run setup after View Transitions
document.addEventListener('astro:after-swap', () => {
// Reset initialization flag to allow re-setup
window.languageDropdownInitialized = false;
setupLanguageDropdown();
window.languageDropdownInitialized = true;
});
// Listen for popstate events (browser back/forward buttons)
window.addEventListener('popstate', (_event) => {

View File

@@ -35,8 +35,15 @@ import { UI } from 'astrowind:config';
let eventListeners = [];
function removeAllEventListeners() {
// Try to remove listeners, but don't fail if elements are gone
eventListeners.forEach(({ element, event, handler }) => {
element.removeEventListener(event, handler);
try {
if (element && element.removeEventListener) {
element.removeEventListener(event, handler);
}
} catch (e) {
// Element might have been removed from DOM, silently continue
}
});
eventListeners = [];
}
@@ -53,7 +60,7 @@ import { UI } from 'astrowind:config';
}
const onLoad = function () {
// Remove old event listeners before attaching new ones
// Clear old event listeners before attaching new ones
removeAllEventListeners();
let lastKnownScrollPosition = window.scrollY;