Refactor navbar into separate component, fix dropdown menu and dark mode

This commit is contained in:
DylanBarnes 2026-05-10 12:21:43 +00:00
parent d6b1711065
commit d61c23d6a9
13 changed files with 250 additions and 310 deletions

30
components/navbar.html Normal file
View file

@ -0,0 +1,30 @@
<header id="main-header">
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html" class="nav-link">Start</a></li>
<li><a href="ueber_uns.html" class="nav-link">Über uns</a></li>
<li><a href="team.html" class="nav-link">Team</a></li>
<li><a href="eis_projekt.html" class="nav-link">Projekt</a></li>
<li><a href="kontakt.html" class="nav-link">Kontakt</a></li>
<li><a href="impressum.html" class="nav-link">Impressum</a></li>
<li class="dropdown-menu-item">
<a href="#" class="dropdown-toggle nav-link">Übungen ▼</a>
<ul class="dropdown-submenu">
<li><a href="notenrechner.html" class="nav-link">Notenrechner</a></li>
<li><a href="textanalyse.html" class="nav-link">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" class="nav-link">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle" class="dark-mode-btn">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>

View file

@ -83,6 +83,48 @@ header {
display: block;
}
/* New dropdown submenu styles for component */
.dropdown-submenu {
position: absolute;
top: 100%;
left: 0;
background: rgba(0, 0, 0, 0.2);
border-radius: 8px;
min-width: 220px;
list-style: none;
padding: 0.5rem 0;
margin: 0.5rem 0 0 0;
display: none;
flex-direction: column;
z-index: 1001;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px);
}
.dropdown-submenu.show {
display: flex;
}
.dropdown-submenu li {
list-style: none;
padding: 0;
}
.dropdown-submenu li a {
display: block;
padding: 0.7rem 1.25rem;
white-space: nowrap;
color: rgba(255, 255, 255, 0.95);
transition: all 0.2s ease;
text-decoration: none;
}
.dropdown-submenu li a:hover {
background: rgba(255, 255, 255, 0.15);
padding-left: 1.5rem;
color: white;
}
.nav-menu a {
text-decoration: none;
color: rgba(255, 255, 255, 0.9);
@ -1162,6 +1204,18 @@ body.dark .exercise-card td {
color: #a0aec0;
}
body.dark .dropdown-submenu {
background: rgba(0, 0, 0, 0.4);
}
body.dark .dropdown-submenu li a {
color: rgba(226, 232, 240, 0.95);
}
body.dark .dropdown-submenu li a:hover {
background: rgba(226, 232, 240, 0.15);
}
body.dark .exercise-card th {
background-color: #2d3e5f;
color: #e2e8f0;

View file

@ -11,37 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html" class="active">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="page-header">
@ -128,6 +97,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>

View file

@ -11,37 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html" class="active">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="page-header">
@ -191,6 +160,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>

View file

@ -11,37 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html" class="active">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="hero">
@ -99,6 +68,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>

156
js/navbar.js Normal file
View file

@ -0,0 +1,156 @@
// ====================== NAVBAR COMPONENT LOADER ======================
/**
* Determine the correct path to the navbar component based on current page
*/
function getNavbarPath() {
const path = window.location.pathname;
// Check if we're in a subdirectory
if (path.includes('/notenrechner') || path.includes('/textanalyse')) {
return '../components/navbar.html';
}
return 'components/navbar.html';
}
/**
* Load the navbar component into the page
*/
async function loadNavbar() {
try {
const navbarPath = getNavbarPath();
const response = await fetch(navbarPath);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const html = await response.text();
// Insert navbar at the beginning of body
document.body.insertAdjacentHTML('afterbegin', html);
// Set the active nav link based on current page
setActiveNavLink();
// Initialize navbar functionality
initializeNavbar();
// Initialize dark mode
initializeDarkMode();
} catch (error) {
console.error('Error loading navbar:', error);
// Fallback: Create a basic navbar if loading fails
createFallbackNavbar();
}
}
/**
* Set the active class on the current page's nav link
*/
function setActiveNavLink() {
const currentPage = window.location.pathname.split('/').pop() || 'index.html';
const navLinks = document.querySelectorAll('.nav-link');
navLinks.forEach(link => {
const href = link.getAttribute('href');
if (href === currentPage || (currentPage === '' && href === 'index.html')) {
link.classList.add('active');
}
});
}
/**
* Initialize navbar interactions (hamburger menu, dropdown)
*/
function initializeNavbar() {
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
const dropdownToggle = document.querySelector('.dropdown-toggle');
const dropdownSubmenu = document.querySelector('.dropdown-submenu');
// Mobile hamburger menu toggle
if (hamburger && navMenu) {
hamburger.addEventListener('click', () => {
navMenu.classList.toggle('active');
});
// Close menu when a nav link is clicked
document.querySelectorAll('.nav-menu .nav-link').forEach(link => {
link.addEventListener('click', (e) => {
// Don't close for the dropdown toggle
if (link.classList.contains('dropdown-toggle')) {
return;
}
navMenu.classList.remove('active');
});
});
}
// Dropdown menu toggle
if (dropdownToggle && dropdownSubmenu) {
dropdownToggle.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
dropdownSubmenu.classList.toggle('show');
});
// Close dropdown when a submenu link is clicked
dropdownSubmenu.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
dropdownSubmenu.classList.remove('show');
navMenu.classList.remove('active');
});
});
// Close dropdown when clicking outside
document.addEventListener('click', (e) => {
if (!e.target.closest('.dropdown-menu-item')) {
dropdownSubmenu.classList.remove('show');
}
});
}
}
/**
* Initialize Dark Mode functionality
*/
function initializeDarkMode() {
const toggle = document.getElementById('dark-mode-toggle');
if (!toggle) return;
// Restore saved dark mode state on page load
if (localStorage.getItem('darkMode') === 'true') {
document.documentElement.setAttribute('data-theme', 'dark');
document.body.classList.add('dark');
toggle.textContent = '☀️ Light Mode';
}
// Toggle dark mode on button click
toggle.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
const isDark = document.body.classList.toggle('dark');
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
localStorage.setItem('darkMode', isDark);
toggle.textContent = isDark ? '☀️ Light Mode' : '🌙 Dark Mode';
});
}
/**
* Fallback navbar creation if component loading fails
*/
function createFallbackNavbar() {
console.warn('Using fallback navbar creation');
// This can be implemented if needed
}
// Load navbar when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadNavbar);
} else {
loadNavbar();
}

View file

@ -1,38 +1,3 @@
// ====================== MOBILE MENU TOGGLE ======================
document.addEventListener('DOMContentLoaded', () => {
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
if (hamburger) {
hamburger.addEventListener('click', () => {
navMenu.classList.toggle('active');
});
// Close menu when a link is clicked
document.querySelectorAll('.nav-menu a').forEach(link => {
link.addEventListener('click', () => {
navMenu.classList.remove('active');
});
});
}
});
// ====================== ACTIVE NAV HIGHLIGHTING ======================
document.addEventListener('DOMContentLoaded', () => {
const currentLocation = location.pathname;
const navLinks = document.querySelectorAll('.nav-menu a');
navLinks.forEach(link => {
if (link.getAttribute('href') === currentLocation) {
link.classList.add('active');
} else {
link.classList.remove('active');
}
});
});
// ====================== CONTACT FORM VALIDATION ======================
const contactForm = document.getElementById('contactForm');
@ -282,27 +247,4 @@ document.querySelectorAll('.content-section').forEach(section => {
// ====================== UTILITY: CONSOLE MESSAGE ======================
console.log('%c🎉 Welcome to EIS Project!', 'color: #2563eb; font-size: 20px; font-weight: bold;');
console.log('%cThis website is a learning project for interactive software development at PH Weingarten.', 'color: #475569; font-size: 14px;');
// ====================== DARK MODE TOGGLE ======================
document.addEventListener("DOMContentLoaded", () => {
const toggle = document.getElementById("dark-mode-toggle");
if (!toggle) return;
// Beim Laden: gespeicherten Zustand wiederherstellen
if (localStorage.getItem("darkMode") === "true") {
document.body.classList.add("dark");
toggle.textContent = "☀️ Light Mode";
}
// Beim Klick: Zustand umschalten und speichern
toggle.addEventListener("click", (e) => {
e.preventDefault();
document.body.classList.toggle("dark");
const isDark = document.body.classList.contains("dark");
localStorage.setItem("darkMode", isDark);
toggle.textContent = isDark ? "☀️ Light Mode" : "🌙 Dark Mode";
});
});
console.log('%cThis website is a learning project for interactive software development at PH Weingarten.', 'color: #475569; font-size: 14px;');

View file

@ -10,36 +10,6 @@
</head>
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html" class="active">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
@ -139,6 +109,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>

View file

@ -12,28 +12,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="content-section">
<div class="container">
@ -110,6 +88,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/notenrechner-dom.js"></script>
<script src="js/script.js"></script>

View file

@ -11,28 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="content-section">
<div class="container">
@ -88,6 +66,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/notenrechner.js"></script>
<script src="js/script.js"></script>

View file

@ -142,37 +142,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Mayonaize Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html" class="active">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="hero">
@ -262,6 +231,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>

View file

@ -11,28 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="content-section">
<div class="container">
@ -74,6 +52,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/textanalyse.js"></script>
<script src="js/script.js"></script>

View file

@ -11,37 +11,6 @@
<body>
<header>
<nav class="navbar">
<div class="nav-container">
<div class="logo">EIS Projekt</div>
<ul class="nav-menu">
<li><a href="index.html">Start</a></li>
<li><a href="ueber_uns.html" class="active">Über uns</a></li>
<li><a href="team.html">Team</a></li>
<li><a href="eis_projekt.html">Projekt</a></li>
<li><a href="kontakt.html">Kontakt</a></li>
<li><a href="impressum.html">Impressum</a></li>
<li style="position: relative;">
<a href="#" style="padding: 0.4rem 0.8rem;">Übungen ▼</a>
<ul style="position: absolute; top: 100%; left: 0; background: rgba(0, 0, 0, 0.1); border-radius: 8px; min-width: 200px; list-style: none; padding: 0.5rem 0; margin: 0.5rem 0 0 0; display: none;">
<li><a href="notenrechner.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner</a></li>
<li><a href="textanalyse.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Textanalyse</a></li>
<li><a href="notenrechner-dom.html" style="display: block; padding: 0.5rem 1rem; white-space: nowrap;">Notenrechner (DOM)</a></li>
</ul>
</li>
<li><a href="assets/projektinfo.pdf" download class="btn-download">PDF ↓</a></li>
<li><button id="dark-mode-toggle">🌙 Dark Mode</button></li>
</ul>
<div class="hamburger">
<span></span>
<span></span>
<span></span>
</div>
</div>
</nav>
</header>
<main>
<section class="page-header">
@ -122,6 +91,7 @@
</div>
</footer>
<script src="js/navbar.js"></script>
<script src="js/script.js"></script>
</body>