打开/关闭搜索
搜索
打开/关闭菜单
6629
8
8126
OGAS数据中枢
导航
首页
最近更改
随机页面
特殊页面
批量上传
上传文件
Special:BatchUpload|批量上传
打开/关闭外观设置菜单
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
查看“︁Widget:Countdown”︁的源代码
来自OGAS数据中枢
分享此页面
更多语言
查看
阅读
查看源代码
查看历史
associated-pages
页面
讨论
更多操作
←
Widget:Countdown
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
管理员
您可以查看和复制此页面的源代码。
<noinclude>仅供{{tl|Countdown}}使用。</noinclude><includeonly><!--{if !isset($wgCountdown) || !$wgCountdown}--><!--{assign var="wgCountdown" value=true scope="global"}--><script> "use strict"; (function() { // 如果 moment 已经存在,直接初始化 if (typeof moment !== 'undefined') { initCountdown(); return; } // 检查是否支持 mw.loader if (typeof mw !== 'undefined' && mw.loader && typeof mw.loader.using === 'function') { mw.loader.using('moment').then(initCountdown).catch(loadFromCDN); } else { // mw.loader 不可用,直接从 CDN 加载 loadFromCDN(); } function loadFromCDN() { // 国内 CDN 备选列表 var cdnList = [ 'https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.4/moment.min.js', 'https://cdn.staticfile.org/moment.js/2.29.4/moment.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js' ]; tryLoadCDN(0); function tryLoadCDN(index) { if (index >= cdnList.length) { // 所有 CDN 都失败 document.querySelectorAll('.countdownNode').forEach(el => { el.textContent = '(无法加载时间库)'; el.classList.add('error'); }); return; } var script = document.createElement('script'); script.src = cdnList[index]; script.onload = initCountdown; script.onerror = function() { tryLoadCDN(index + 1); // 尝试下一个 CDN }; document.head.appendChild(script); } } function initCountdown() { // 确保 DOM 加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', setupCountdown); } else { setupCountdown(); } } function setupCountdown() { const fromNow = (then, before, after, on) => { const now = moment(); const isBefore = then.isBefore(now); const monthsHave31Days = [0, 2, 4, 6, 7, 9, 11]; let year = isBefore ? now.year() - then.year() : then.year() - now.year(), month = isBefore ? now.month() - then.month() : then.month() - now.month(), day = isBefore ? now.date() - then.date() : then.date() - now.date(), hour = isBefore ? now.hour() - then.hour() : then.hour() - now.hour(), minute = isBefore ? now.minute() - then.minute() : then.minute() - now.minute(), second = isBefore ? now.second() - then.second() : then.second() - now.second(); if (second < 0) { minute--; second += 60; } if (minute < 0) { hour--; minute += 60; } if (hour < 0) { day--; hour += 24; } if (day < 0) { month--; if (monthsHave31Days.includes((isBefore ? then : now).month())) { day += 31; } else if ((isBefore ? then : now).month() === 1) { if ((isBefore ? then : now).year() % 4 === 0) { day += 29; } else { day += 28; } } else { day += 30; } } if (month < 0) { year--; month += 12; } let result = ""; if (year > 0) { result += `${year}年`; } if (month > 0) { result += `${month}月`; } else if (result !== "") { result += `${0}月`; } if (day > 0) { result += `${day}日`; } else if (result !== "") { result += `${0}日`; } if (hour > 0) { result += `${hour}小时`; } else if (result !== "") { result += `${0}小时`; } if (minute > 0) { result += `${minute}分`; } else if (result !== "") { result += `${0}分`; } if (second > 0) { result += `${second}秒`; } else if (result !== "") { result += `${0}秒`; } return (result === "" ? on : isBefore ? before : after).replace("$1", result.replace(/(\d) /g, "$1")); }; const run = () => { if (typeof jQuery === 'undefined') { // 如果没有 jQuery,使用原生方法 document.querySelectorAll(".countdownNode:not(.disabled)").forEach(ele => { const time = moment(ele.dataset.target); if (time && time.isValid()) { ele.textContent = fromNow(time, ele.dataset.before || "$1前", ele.dataset.after || "还剩$1", ele.dataset.on || "就是现在!"); } }); } else { // 有 jQuery 就用 jQuery jQuery(".countdownNode:not(.disabled)").each((_, ele) => { const self = jQuery(ele); self.text(fromNow(self.data("target"), ele.dataset.before || "$1前", ele.dataset.after || "还剩$1", ele.dataset.on || "就是现在!")); }); } }; // 初始化所有倒计时节点 if (typeof jQuery === 'undefined') { // 原生方式 document.querySelectorAll(".countdownNode").forEach(ele => { const time = moment(ele.dataset.target); if (!time || !time.isValid()) { ele.classList.add("error", "disabled"); ele.textContent = "(发生了致命错误!)"; } else { ele._countdownTarget = time; } }); } else { // jQuery 方式 jQuery(".countdownNode").each((_, ele) => { const self = jQuery(ele), time = moment(ele.dataset.target); if (!time || !time.isValid()) { self.addClass("error disabled").text("(发生了致命错误!)"); return; } self.data("target", time); }); } run(); window.setInterval(run, 1000); } })(); </script><!--{/if}--></includeonly>
该页面嵌入的页面:
Template:Tl
(
查看源代码
)
Template:Transclude
(
查看源代码
)
返回
Widget:Countdown
。
查看“︁Widget:Countdown”︁的源代码
来自OGAS数据中枢