Files
aifo-portal-web/js/landing-countdown.js
2026-07-30 18:38:39 +08:00

73 lines
2.1 KiB
JavaScript

/**
* Flip-style countdown for landing pages.
* Usage:
* <div class="landing-countdown" data-countdown data-countdown-end="2026-12-31T23:59:59">
* <div class="landing-countdown" data-countdown data-countdown-days="10">
*/
(function () {
function pad2(n) {
return String(Math.max(0, n)).padStart(2, "0");
}
function renderDigits(container, value) {
var digits = container.querySelectorAll("[data-countdown-digit]");
var str = pad2(value);
digits[0].textContent = str[0];
digits[1].textContent = str[1];
}
function resolveEndTime(el) {
var daysAttr = el.getAttribute("data-countdown-days");
if (daysAttr != null && daysAttr !== "") {
var days = parseInt(daysAttr, 10);
if (!Number.isNaN(days) && days >= 0) {
var end = new Date();
end.setDate(end.getDate() + days);
end.setHours(23, 59, 59, 999);
return end.getTime();
}
}
var endStr = el.getAttribute("data-countdown-end");
if (!endStr) return NaN;
return new Date(endStr).getTime();
}
function initCountdown(el) {
var end = resolveEndTime(el);
if (Number.isNaN(end)) return;
var daysEl = el.querySelector("[data-countdown-days]");
var hoursEl = el.querySelector("[data-countdown-hours]");
var minsEl = el.querySelector("[data-countdown-mins]");
var secsEl = el.querySelector("[data-countdown-secs]");
function tick() {
var diff = Math.max(0, end - Date.now());
var totalSec = Math.floor(diff / 1000);
var days = Math.floor(totalSec / 86400);
var hours = Math.floor((totalSec % 86400) / 3600);
var mins = Math.floor((totalSec % 3600) / 60);
var secs = totalSec % 60;
if (daysEl) renderDigits(daysEl, days);
if (hoursEl) renderDigits(hoursEl, hours);
if (minsEl) renderDigits(minsEl, mins);
if (secsEl) renderDigits(secsEl, secs);
}
tick();
setInterval(tick, 1000);
}
function initAll() {
document.querySelectorAll("[data-countdown]").forEach(initCountdown);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initAll);
} else {
initAll();
}
})();