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:59:56 +02:00
|
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
2026-05-29 22:34:27 +02:00
|
|
|
<style>
|
2026-05-29 22:59:56 +02:00
|
|
|
/* Fade-Transition (wird per JS .fade-out Klasse getoggelt) */
|
|
|
|
|
#joke { transition: opacity .5s ease; }
|
2026-05-29 22:34:27 +02:00
|
|
|
#joke.fade-out { opacity: 0; }
|
|
|
|
|
</style>
|
2026-05-29 21:56:12 +02:00
|
|
|
</head>
|
2026-05-29 22:59:56 +02:00
|
|
|
<body class="min-h-screen flex items-center justify-center bg-stone-100 text-zinc-900 font-sans antialiased p-4 sm:p-8">
|
|
|
|
|
<div class="w-full max-w-[600px] bg-white rounded-2xl shadow-lg px-6 py-8 text-center">
|
|
|
|
|
<h1 class="text-2xl font-bold mb-6">Witze-Ticker</h1>
|
2026-05-29 22:34:27 +02:00
|
|
|
|
|
|
|
|
<div id="joke-container">
|
2026-05-29 22:59:56 +02:00
|
|
|
<div id="joke" class="text-lg sm:text-xl leading-relaxed min-h-[120px] flex items-center justify-center"></div>
|
2026-05-29 22:34:27 +02:00
|
|
|
</div>
|
|
|
|
|
|
2026-05-29 22:59:56 +02:00
|
|
|
<div class="mt-4 text-sm text-zinc-500 flex justify-center gap-5">
|
2026-05-29 22:34:27 +02:00
|
|
|
<span id="index-display"></span>
|
|
|
|
|
<span id="countdown-display"></span>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-29 22:59:56 +02:00
|
|
|
<div class="mt-6 flex flex-col sm:flex-row items-center justify-center gap-3">
|
|
|
|
|
<button id="prev-btn" class="w-full sm:w-auto px-5 py-2.5 text-base rounded-lg bg-gray-500 text-white cursor-pointer transition-colors duration-200 hover:bg-gray-600 active:bg-gray-700">Vorheriger Witz</button>
|
|
|
|
|
<button id="next-btn" class="w-full sm:w-auto px-5 py-2.5 text-base rounded-lg bg-blue-600 text-white cursor-pointer transition-colors duration-200 hover:bg-blue-700 active:bg-blue-800">Nächster Witz</button>
|
|
|
|
|
</div>
|
2026-05-29 22:34:27 +02:00
|
|
|
</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;
|
2026-05-29 22:59:56 +02:00
|
|
|
var jokeHistory = []; // joke indices in visit order
|
|
|
|
|
var historyPos = -1; // current position in jokeHistory
|
2026-05-29 22:34:27 +02:00
|
|
|
|
|
|
|
|
var jokeEl = document.getElementById('joke');
|
|
|
|
|
var indexEl = document.getElementById('index-display');
|
|
|
|
|
var countdownEl = document.getElementById('countdown-display');
|
|
|
|
|
var nextBtn = document.getElementById('next-btn');
|
2026-05-29 22:59:56 +02:00
|
|
|
var prevBtn = document.getElementById('prev-btn');
|
2026-05-29 22:34:27 +02:00
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 22:59:56 +02:00
|
|
|
// Vorherigen Witz anzeigen
|
|
|
|
|
function prevJoke() {
|
|
|
|
|
if (historyPos <= 0) return;
|
|
|
|
|
historyPos--;
|
|
|
|
|
showJoke(jokeHistory[historyPos]);
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 22:34:27 +02:00
|
|
|
// Countdown-Anzeige aktualisieren
|
|
|
|
|
function updateCountdownDisplay() {
|
|
|
|
|
countdownEl.textContent = 'N\u00e4chster Witz in ' + countdownSeconds + ' s';
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-29 22:59:56 +02:00
|
|
|
// Countdown starten (ein einziger Timer \u2014 bei 0 wird nextJoke aufgerufen)
|
2026-05-29 22:34:27 +02:00
|
|
|
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() {
|
2026-05-29 22:59:56 +02:00
|
|
|
// Vorw\u00e4rts-History verwerfen, neuen Witz anh\u00e4ngen
|
|
|
|
|
jokeHistory.splice(historyPos + 1);
|
2026-05-29 22:34:27 +02:00
|
|
|
var idx = randomIndex();
|
2026-05-29 22:59:56 +02:00
|
|
|
jokeHistory.push(idx);
|
|
|
|
|
historyPos = jokeHistory.length - 1;
|
2026-05-29 22:34:27 +02:00
|
|
|
showJoke(idx);
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialer Zufallswitz beim Laden
|
|
|
|
|
function init() {
|
2026-05-29 22:59:56 +02:00
|
|
|
var idx = Math.floor(Math.random() * jokes.length);
|
2026-05-29 22:34:27 +02:00
|
|
|
currentIndex = idx;
|
2026-05-29 22:59:56 +02:00
|
|
|
jokeHistory.push(idx);
|
|
|
|
|
historyPos = 0;
|
2026-05-29 22:34:27 +02:00
|
|
|
jokeEl.textContent = jokes[idx];
|
|
|
|
|
indexEl.textContent = (idx + 1) + '/' + jokes.length;
|
|
|
|
|
startCountdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Event-Listener
|
|
|
|
|
nextBtn.addEventListener('click', function () {
|
|
|
|
|
nextJoke();
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-29 22:59:56 +02:00
|
|
|
prevBtn.addEventListener('click', function () {
|
|
|
|
|
prevJoke();
|
|
|
|
|
});
|
|
|
|
|
|
2026-05-29 22:34:27 +02:00
|
|
|
document.addEventListener('visibilitychange', function () {
|
|
|
|
|
if (document.hidden) {
|
|
|
|
|
pauseCountdown();
|
|
|
|
|
} else {
|
|
|
|
|
resumeCountdown();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Start
|
|
|
|
|
init();
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
2026-05-29 21:56:12 +02:00
|
|
|
</body>
|
|
|
|
|
</html>
|