DOGFATHER UNIVERSE: erste lauffähige Website + Bewerbungs-Postfach + Hosting-Vorbereitung
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
/* =====================================================================
|
||||
DOGFATHER UNIVERSE — main.js
|
||||
Gemeinsame Navigation, mobiles Menü, Footer, Nebel-Effekt.
|
||||
Läuft rein clientseitig (kein Build-Tool, kein Fetch von Partials),
|
||||
damit jede Seite auch direkt per Doppelklick (file://) funktioniert.
|
||||
===================================================================== */
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
/* ---------- Navigationsstruktur (an einer Stelle pflegen) ---------- */
|
||||
const NAV = [
|
||||
{ label: "Start", href: "index.html" },
|
||||
{
|
||||
label: "Dogfather",
|
||||
children: [
|
||||
{ label: "Die Person", href: "dogfather.html" },
|
||||
{ label: "Streamer", href: "streamer.html" },
|
||||
{ label: "Streamplan", href: "streamplan.html" },
|
||||
{ label: "Zeitreise", href: "zeitreise.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "HasiDog",
|
||||
children: [
|
||||
{ label: "HasiDog-Welt", href: "hasidog.html" },
|
||||
{ label: "Kasper", href: "kasper.html" },
|
||||
{ label: "Community", href: "community.html" },
|
||||
{ label: "Stimmen", href: "stimmen.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Manager",
|
||||
children: [
|
||||
{ label: "Manager Dogfather", href: "manager.html" },
|
||||
{ label: "Werte", href: "werte.html" },
|
||||
{ label: "Scout-Team", href: "team-scouts.html" },
|
||||
{ label: "Modi-Team", href: "team-modis.html" },
|
||||
{ label: "VanVan", href: "vanvan.html" },
|
||||
{ label: "Creator", href: "creator.html" },
|
||||
{ label: "Bewerben", href: "bewerben.html" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Medien",
|
||||
children: [
|
||||
{ label: "Galerie", href: "medien.html" },
|
||||
{ label: "Videos", href: "videos.html" },
|
||||
{ label: "Aktionen", href: "aktionen.html" },
|
||||
],
|
||||
},
|
||||
{ label: "Links", href: "links.html" },
|
||||
];
|
||||
|
||||
const currentFile = (location.pathname.split("/").pop() || "index.html");
|
||||
|
||||
function isActive(href) {
|
||||
return href === currentFile;
|
||||
}
|
||||
|
||||
function renderNavItem(item) {
|
||||
if (!item.children) {
|
||||
return `<a class="nav-flat${isActive(item.href) ? " active" : ""}" href="${item.href}">${item.label}</a>`;
|
||||
}
|
||||
const activeChild = item.children.some((c) => isActive(c.href));
|
||||
return `
|
||||
<div class="nav-group${activeChild ? " open-hint" : ""}">
|
||||
<button type="button" aria-expanded="false">${item.label} <span aria-hidden="true">▾</span></button>
|
||||
<div class="nav-dropdown">
|
||||
${item.children
|
||||
.map(
|
||||
(c) =>
|
||||
`<a href="${c.href}"${isActive(c.href) ? ' class="active"' : ""}>${c.label}</a>`
|
||||
)
|
||||
.join("")}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function renderHeader() {
|
||||
const el = document.getElementById("site-header");
|
||||
if (!el) return;
|
||||
el.innerHTML = `
|
||||
<header class="site-header">
|
||||
<div class="nav-bar">
|
||||
<a class="brand" href="index.html">
|
||||
<span class="heart">🩵</span>
|
||||
<span>DOGFATHER UNIVERSE
|
||||
<small>Streamer · Community · HasiDog · Manager</small>
|
||||
</span>
|
||||
</a>
|
||||
<button class="nav-toggle" type="button" aria-label="Menü öffnen" aria-expanded="false">☰</button>
|
||||
<nav class="nav-links">
|
||||
${NAV.map(renderNavItem).join("")}
|
||||
<a class="nav-cta" href="bewerben.html">Bewerben 🩵</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>`;
|
||||
|
||||
const toggle = el.querySelector(".nav-toggle");
|
||||
const links = el.querySelector(".nav-links");
|
||||
toggle.addEventListener("click", () => {
|
||||
const open = links.classList.toggle("open");
|
||||
toggle.setAttribute("aria-expanded", String(open));
|
||||
});
|
||||
|
||||
el.querySelectorAll(".nav-group > button").forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
const group = btn.parentElement;
|
||||
const wasOpen = group.classList.contains("open");
|
||||
el.querySelectorAll(".nav-group.open").forEach((g) => g.classList.remove("open"));
|
||||
if (!wasOpen) group.classList.add("open");
|
||||
btn.setAttribute("aria-expanded", String(!wasOpen));
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!el.contains(e.target)) {
|
||||
el.querySelectorAll(".nav-group.open").forEach((g) => g.classList.remove("open"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderFooter() {
|
||||
const el = document.getElementById("site-footer");
|
||||
if (!el) return;
|
||||
const year = new Date().getFullYear();
|
||||
el.innerHTML = `
|
||||
<footer class="site-footer">
|
||||
<div class="container footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="heart">🩵</span> DOGFATHER UNIVERSE</div>
|
||||
<p class="small" style="margin-top:.8rem;max-width:32ch;">
|
||||
Streamer. Community. HasiDog. Manager. Gemeinsam stark.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Dogfather</h4>
|
||||
<ul>
|
||||
<li><a href="dogfather.html">Die Person</a></li>
|
||||
<li><a href="streamer.html">Streamer</a></li>
|
||||
<li><a href="zeitreise.html">Zeitreise</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>HasiDog & Manager</h4>
|
||||
<ul>
|
||||
<li><a href="hasidog.html">HasiDog-Welt</a></li>
|
||||
<li><a href="manager.html">Manager Dogfather</a></li>
|
||||
<li><a href="team-scouts.html">Scouts</a></li>
|
||||
<li><a href="team-modis.html">Modis</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Mehr</h4>
|
||||
<ul>
|
||||
<li><a href="links.html">Alle Links</a></li>
|
||||
<li><a href="bewerben.html">Bewerben</a></li>
|
||||
<li><a href="kontakt.html">Kontakt</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container footer-bottom">
|
||||
<span>© ${year} Dogfather Universe. Team Dogi ist Familie 🩵</span>
|
||||
<span><a href="kontakt.html">Impressum & Datenschutz</a> · <a href="postfach.html">Team-Postfach 🔒</a></span>
|
||||
</div>
|
||||
</footer>`;
|
||||
}
|
||||
|
||||
function renderFog() {
|
||||
if (document.querySelector(".fog-layer")) return;
|
||||
const layer = document.createElement("div");
|
||||
layer.className = "fog-layer";
|
||||
layer.setAttribute("aria-hidden", "true");
|
||||
const blobs = 6;
|
||||
let html = "";
|
||||
for (let i = 0; i < blobs; i++) {
|
||||
const size = 220 + Math.round(Math.random() * 260);
|
||||
const top = Math.round(Math.random() * 100);
|
||||
const left = Math.round(Math.random() * 100);
|
||||
const delay = (Math.random() * 10).toFixed(1);
|
||||
html += `<span style="width:${size}px;height:${size}px;top:${top}%;left:${left}%;animation-delay:${delay}s;"></span>`;
|
||||
}
|
||||
layer.innerHTML = html;
|
||||
document.body.prepend(layer);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
renderHeader();
|
||||
renderFooter();
|
||||
renderFog();
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user