2026-05-29 21:56:12 +02:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="de">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
2026-05-29 22:34:27 +02:00
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
2026-05-29 21:56:12 +02:00
|
|
|
<title>Witze-Ticker</title>
|
2026-05-29 22:34:27 +02:00
|
|
|
<style>
|
|
|
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
|
|
|
background: #f4f4f5;
|
|
|
|
|
color: #18181b;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 2rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.card {
|
|
|
|
|
background: #fff;
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
box-shadow: 0 4px 24px rgba(0,0,0,.08);
|
|
|
|
|
max-width: 600px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
padding: 2.5rem 2rem 2rem;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h1 { font-size: 1.5rem; margin-bottom: 1.5rem; }
|
|
|
|
|
|
|
|
|
|
/* Witz-Bereich mit Fade-Transition */
|
|
|
|
|
#joke-container {
|
|
|
|
|
min-height: 120px;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#joke {
|
|
|
|
|
font-size: 1.15rem;
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transition: opacity .5s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#joke.fade-out { opacity: 0; }
|
|
|
|
|
|
|
|
|
|
/* Meta-Zeile: Index + Countdown */
|
|
|
|
|
.meta {
|
|
|
|
|
margin-top: 1rem;
|
|
|
|
|
font-size: .85rem;
|
|
|
|
|
color: #71717a;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
gap: 1.25rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Button */
|
|
|
|
|
#next-btn {
|
|
|
|
|
margin-top: 1.5rem;
|
|
|
|
|
padding: .65rem 1.5rem;
|
|
|
|
|
font-size: 1rem;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
background: #2563eb;
|
|
|
|
|
color: #fff;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: background .2s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#next-btn:hover { background: #1d4ed8; }
|
|
|
|
|
#next-btn:active { background: #1e40af; }
|
|
|
|
|
</style>
|
2026-05-29 21:56:12 +02:00
|
|
|
</head>
|
|
|
|
|
<body>
|
2026-05-29 22:34:27 +02:00
|
|
|
<div class="card">
|
|
|
|
|
<h1>Witze-Ticker</h1>
|
|
|
|
|
|
|
|
|
|
<div id="joke-container">
|
|
|
|
|
<div id="joke"></div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="meta">
|
|
|
|
|
<span id="index-display"></span>
|
|
|
|
|
<span id="countdown-display"></span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button id="next-btn">Nächster Witz</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
(function () {
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var jokes = [
|
|
|
|
|
"Why don't scientists trust atoms? Because they make up everything.",
|
|
|
|
|
"I told my wife she was drawing her eyebrows too high. She looked surprised.",
|
|
|
|
|
"Why do programmers prefer dark mode? Because light attracts bugs.",
|
|
|
|
|
"I asked the librarian if they had books about paranoia. She whispered: 'They're right behind you.'",
|
|
|
|
|
"A skeleton walks into a bar and orders a beer \u2014 and a mop.",
|
|
|
|
|
"Why did the scarecrow win an award? Because he was outstanding in his field.",
|
|
|
|
|
"I'm reading a book about anti-gravity. It's impossible to put down.",
|
|
|
|
|
"Why do cows wear bells? Because their horns don't work.",
|
|
|
|
|
"I told my dog he was adopted. He said: 'I knew it \u2014 you throw like a human.'",
|
|
|
|
|
"What do you call a fish without eyes? A fsh.",
|
|
|
|
|
"Why can't you trust stairs? They're always up to something.",
|
|
|
|
|
"I used to hate facial hair, but then it grew on me.",
|
|
|
|
|
"Why did the bicycle fall over? Because it was two-tired.",
|
|
|
|
|
"What do you call cheese that isn't yours? Nacho cheese.",
|
|
|
|
|
"I tried to write a joke about clocks but it was time-consuming.",
|
|
|
|
|
"Why did the math book look so sad? It had too many problems.",
|
|
|
|
|
"What do you call a sleeping dinosaur? A dino-snore.",
|
|
|
|
|
"I told my cat a joke. He didn't laugh. Tough crowd.",
|
|
|
|
|
"Why don't eggs tell jokes? They'd crack each other up.",
|
|
|
|
|
"What's a vampire's favourite fruit? A blood orange. Just kidding \u2014 neck-tarines.",
|
|
|
|
|
"Why did the coffee file a police report? It got mugged.",
|
|
|
|
|
"I asked my dog what two minus two is. He said nothing.",
|
|
|
|
|
"What do you call a fake noodle? An impasta.",
|
|
|
|
|
"Why did the golfer bring an extra pair of trousers? In case he got a hole in one.",
|
|
|
|
|
"I have a joke about construction, but I'm still working on it."
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
var COUNTDOWN_SECONDS = 60;
|
|
|
|
|
var currentIndex = -1;
|
|
|
|
|
var countdownSeconds = COUNTDOWN_SECONDS;
|
|
|
|
|
var fadeTimeout = null;
|
|
|
|
|
var countdownInterval = null;
|
|
|
|
|
|
|
|
|
|
var jokeEl = document.getElementById('joke');
|
|
|
|
|
var indexEl = document.getElementById('index-display');
|
|
|
|
|
var countdownEl = document.getElementById('countdown-display');
|
|
|
|
|
var nextBtn = document.getElementById('next-btn');
|
|
|
|
|
|
|
|
|
|
// Zuf\u00e4lligen Index w\u00e4hlen (nicht derselbe wie der aktuelle)
|
|
|
|
|
function randomIndex() {
|
|
|
|
|
var idx;
|
|
|
|
|
do { idx = Math.floor(Math.random() * jokes.length); }
|
|
|
|
|
while (idx === currentIndex && jokes.length > 1);
|
|
|
|
|
return idx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Witz anzeigen mit Fade-\u00dcbergang
|
|
|
|
|
function showJoke(idx) {
|
|
|
|
|
clearTimeout(fadeTimeout);
|
|
|
|
|
currentIndex = idx;
|
|
|
|
|
jokeEl.classList.add('fade-out');
|
|
|
|
|
|
|
|
|
|
fadeTimeout = setTimeout(function () {
|
|
|
|
|
jokeEl.textContent = jokes[idx];
|
|
|
|
|
indexEl.textContent = (idx + 1) + '/' + jokes.length;
|
|
|
|
|
jokeEl.classList.remove('fade-out');
|
|
|
|
|
}, 500);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Countdown-Anzeige aktualisieren
|
|
|
|
|
function updateCountdownDisplay() {
|
|
|
|
|
countdownEl.textContent = 'N\u00e4chster Witz in ' + countdownSeconds + ' s';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Countdown starten (ein einziger Timer — bei 0 wird nextJoke aufgerufen)
|
|
|
|
|
function startCountdown() {
|
|
|
|
|
countdownSeconds = COUNTDOWN_SECONDS;
|
|
|
|
|
updateCountdownDisplay();
|
|
|
|
|
|
|
|
|
|
clearInterval(countdownInterval);
|
|
|
|
|
countdownInterval = setInterval(function () {
|
|
|
|
|
countdownSeconds--;
|
|
|
|
|
if (countdownSeconds <= 0) {
|
|
|
|
|
clearInterval(countdownInterval);
|
|
|
|
|
countdownSeconds = 0;
|
|
|
|
|
updateCountdownDisplay();
|
|
|
|
|
nextJoke();
|
|
|
|
|
} else {
|
|
|
|
|
updateCountdownDisplay();
|
|
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Countdown pausieren (Tab in Hintergrund)
|
|
|
|
|
function pauseCountdown() {
|
|
|
|
|
clearInterval(countdownInterval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Countdown fortsetzen (Tab wieder aktiv)
|
|
|
|
|
function resumeCountdown() {
|
|
|
|
|
if (countdownSeconds > 0) {
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// N\u00e4chsten Witz zeigen (manuell oder automatisch)
|
|
|
|
|
function nextJoke() {
|
|
|
|
|
var idx = randomIndex();
|
|
|
|
|
showJoke(idx);
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialer Zufallswitz beim Laden
|
|
|
|
|
function init() {
|
|
|
|
|
var idx = randomIndex();
|
|
|
|
|
currentIndex = idx;
|
|
|
|
|
jokeEl.textContent = jokes[idx];
|
|
|
|
|
indexEl.textContent = (idx + 1) + '/' + jokes.length;
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Event-Listener
|
|
|
|
|
nextBtn.addEventListener('click', function () {
|
|
|
|
|
nextJoke();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.addEventListener('visibilitychange', function () {
|
|
|
|
|
if (document.hidden) {
|
|
|
|
|
pauseCountdown();
|
|
|
|
|
} else {
|
|
|
|
|
resumeCountdown();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Start
|
|
|
|
|
init();
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
2026-05-29 21:56:12 +02:00
|
|
|
</body>
|
|
|
|
|
</html>
|