Widget:Countdown:修订间差异
来自OGAS数据中枢
更多语言
更多操作
imported>弃权者 无编辑摘要 |
imported>弃权者 无编辑摘要 |
||
| 第2行: | 第2行: | ||
"use strict"; | "use strict"; | ||
(function() { | (function() { | ||
if (typeof | // 如果 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 { | } else { | ||
document.querySelectorAll('.countdownNode').forEach(el => { | // 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() { | function initCountdown() { | ||
// 确保 DOM 加载完成 | |||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', setupCountdown); | |||
} else { | |||
setupCountdown(); | |||
} | |||
} | |||
function setupCountdown() { | |||
const fromNow = (then, before, after, on) => { | const fromNow = (then, before, after, on) => { | ||
const now = moment(); | const now = moment(); | ||
| 第92行: | 第129行: | ||
const run = () => { | const run = () => { | ||
$(".countdownNode:not(.disabled)").each((_, ele) => { | 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') { | |||
const self = | // 原生方式 | ||
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); | time = moment(ele.dataset.target); | ||
if (!time || !time.isValid()) { | if (!time || !time.isValid()) { | ||
| 第108行: | 第169行: | ||
self.data("target", time); | self.data("target", time); | ||
}); | }); | ||
} | |||
run(); | |||
window.setInterval(run, 1000); | |||
} | } | ||
})(); | })(); | ||
</script><!--{/if}--></includeonly> | </script><!--{/if}--></includeonly> | ||
2026年3月3日 (二) 08:39的版本
仅供{{Countdown}}使用。