Files
kankys ef2315bac1 Opravy dle TODO.md - kritické a střední priority
- Opraveny chyby v HTML: špatné URL u CDN, chybějící viewport, úvodní apostrof
- Přidány meta description a keywords na všechny stránky
- Odstraněny nestandardní meta tagy (Kankys Matrix)
- Opraveny všechny externí skripty (HTTPS, crossorigin, integrity)
- Vytvořeny sdílené soubory:
  - web/js/shared.js - společné JS funkce (scrollToTop, setupMobileMenu, setupThemeToggle)
  - web/css/variables.css - CSS proměnné pro témata a design
  - web/css/shared.css - sdílené CSS styly
- Založena struktura pro sdílený kód (js/, css/ adresáře)

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-08-10 19:50:00 +02:00

126 lines
3.6 KiB
JavaScript

/**
* Shared JavaScript functions for NewLukasBlog
* Common utilities used across multiple pages
*/
// ============================================
// Mobile Menu (Hamburger Menu)
// ============================================
function setupMobileMenu() {
const menuIcon = document.querySelector(".menu-icon");
const menuList = document.querySelector("nav");
const hamburgerIcon = document.querySelector(".fa-solid");
if (menuIcon && hamburgerIcon && menuList) {
menuIcon.addEventListener("click", () => {
if (hamburgerIcon.classList.contains("fa-bars")) {
hamburgerIcon.classList.add("fa-xmark");
hamburgerIcon.classList.remove("fa-bars");
menuList.style.display = "block";
} else {
hamburgerIcon.classList.add("fa-bars");
hamburgerIcon.classList.remove("fa-xmark");
menuList.style.display = "none";
}
});
}
}
// ============================================
// Scroll to Top Functionality
// ============================================
function scrollToTop() {
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For other browsers
}
function setupScrollToTopButton(buttonId = "scrollToTopBtn") {
const scrollToTopBtn = document.getElementById(buttonId);
if (scrollToTopBtn) {
window.onscroll = function () {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
scrollToTopBtn.style.display = "block";
} else {
scrollToTopBtn.style.display = "none";
}
};
}
}
// ============================================
// Theme Toggle Functionality
// ============================================
// Base theme toggle - can be extended by specific pages
function setupThemeToggle(config = {}) {
const defaults = {
toggleButtonId: "toggleButton",
storageKey: "themePreference",
defaultTheme: "dark"
};
const options = { ...defaults, ...config };
const toggleButton = document.getElementById(options.toggleButtonId);
if (!toggleButton) return;
// Load saved preference or use default
const savedTheme = localStorage.getItem(options.storageKey) || options.defaultTheme;
let isDarkMode = savedTheme === "dark";
// Apply initial theme
if (isDarkMode) {
document.body.classList.add("dark-theme");
} else {
document.body.classList.remove("dark-theme");
}
// Toggle function
function toggleTheme() {
isDarkMode = !isDarkMode;
if (isDarkMode) {
document.body.classList.add("dark-theme");
localStorage.setItem(options.storageKey, "dark");
} else {
document.body.classList.remove("dark-theme");
localStorage.setItem(options.storageKey, "light");
}
// Call custom callback if provided
if (options.onToggle) {
options.onToggle(isDarkMode);
}
}
// Set up click listener
toggleButton.addEventListener("click", toggleTheme);
}
// ============================================
// Image Zoom Functionality
// ============================================
function setupImageZoom(selector = ".picture", scale = 2.2) {
const images = document.querySelectorAll(selector);
images.forEach((img, index) => {
img.addEventListener("mouseenter", () => {
img.style.transform = `scale(${scale})`;
});
img.addEventListener("mouseleave", () => {
img.style.transform = "scale(1)";
});
});
}
// ============================================
// Initialize all common functionality
// ============================================
document.addEventListener("DOMContentLoaded", function() {
setupMobileMenu();
setupScrollToTopButton();
setupThemeToggle();
setupImageZoom();
});