LLWiki正在建设中,欢迎加入我们

“User:Bhsd/widget/countdown.js”的版本间差异

来自LLWiki
跳转到导航 跳转到搜索
标签移动版网页编辑 移动版编辑
 
(未显示同一用户的10个中间版本)
第1行: 第1行:
//<nowiki>
//<nowiki>
// 用于[[Widget:Countdown]],可以使用ES6语法
// 用于[[Widget:Countdown]],可以使用ES6语法
/**
* @Function: 生成倒计时
* @Source: [[moegirl:Widget:Countdown]]
* @Dependencies: moment, ext.gadget.site-lib
* @EditedBy: [[User:Bhsd]]
*/
"use strict";
"use strict";
/*global mw, $, moment, wgUCS*/
(function() {
(() => {
function fromNow(ele, mw) {
let counter, $num;
const now = new Date(),
const fromNow = function() { // 处理一个 .counting 节点,显示时间
then = new Date( ele.dataset.target ),
before = ele.children[0],
const $ele = $(this),
after = ele.children[1],
now = moment(), // now必须是一个新的moment对象
then = moment( $ele.data('target') ), // 必需复制一个moment对象再进行操作
isBefore = (then < now),
monthsHave31Days = [0, 2, 4, 6, 7, 9, 11], // 月份从0开始
isBefore = then.isBefore( now ),
lang = mw.config.get( 'wgUserVariant' ),
[early, late] = isBefore ? [then, now] : [now, then],
isHant = ['zh-hant', 'zh-tw', 'zh-hk', 'zh-mo'].includes( lang ),
year = late.diff( early, 'year' ),
textMonth = isHant ? '個月' : '个月',
month = late.diff( early.add(year, 'year'), 'month' ),
textHour = isHant ? '小時' : '小时';
day = year ? null : late.diff( early.add(month, 'month'), 'day' ),
let year = isBefore ? now.getFullYear() - then.getFullYear() : then.getFullYear() - now.getFullYear(),
hour = year || month ? null : late.diff( early.add(day, 'day'), 'hour' ),
month = isBefore ? now.getMonth() - then.getMonth() : then.getMonth() - now.getMonth(),
minute = year || month || day ? null : late.diff( early.add(hour, 'hour'), 'minute' ),
day = isBefore ? now.getDate() - then.getDate() : then.getDate() - now.getDate(),
second = year || month || day ? null : late.diff( early.add(minute, 'minute'), 'second' ),
result = [
hour = isBefore ? now.getHours() - then.getHours() : then.getHours() - now.getHours(),
minute = isBefore ? now.getMinutes() - then.getMinutes() : then.getMinutes() - now.getMinutes(),
... year ? [$num.clone().text( year ), '年'] : [],
second = isBefore ? now.getSeconds() - then.getSeconds() : then.getSeconds() - now.getSeconds(),
... month ? [$num.clone().text( month ), mw.msg('widget-cd-mm')] : [],
result = "";
... day ? [$num.clone().text( day ), '天'] : [],
... hour ? [$num.clone().text( hour ), mw.msg('widget-cd-hh')] : [],
if (second < 0) {
minute--;
... minute !== null ? [$num.clone().text( minute ), '分'] : [],
second += 60;
... second !== null ? [$num.clone().text( second ), '秒'] : []
}
];
$ele.toggleClass('isBefore', isBefore).children().eq(isBefore ? 0 : 1).find( '.countdown' ).html( result );
if (minute < 0) {
hour--;
},
run = () => { $( '.counting' ).each( fromNow ); }, // 每秒循环一遍所有 .counting 节点
minute += 60;
}
main = ($content) => {
if (hour < 0) {
const $nodes = $content.find( '.countdownNode' );
day--;
if ($nodes.length === 0) { return; }
mw.loader.using( ['moment', 'ext.gadget.site-lib'] ).then(() => {
hour += 24;
mw.messages.set( wgUCS({ 'widget-cd-error': "时间格式错误!", 'widget-cd-mm': '个月', 'widget-cd-hh': '小时' },
}
{ 'widget-cd-error': "時間格式錯誤!", 'widget-cd-mm': '個月', 'widget-cd-hh': '小時' }) );
if (day < 0) {
month--;
$nodes.each(function() {
const $ele = $(this),
if (monthsHave31Days.includes( (isBefore ? then : now).getMonth() )) { day += 31; }
else if ((isBefore ? then : now).getMonth() === 1) {
then = moment(this.title, 'YYYY-MM-DD HH:mm Z');
if ((isBefore ? then : now).getFullYear() % 4 === 0) { day += 29; }
if (then.isValid()) {
else { day += 28; }
$ele.data('target', then).addClass( 'counting' )
// 以本地时间替换title,之后交给[[Widget:Abbr]]就好
}
.attr('title', then.format( 'llll ([UTC]Z' ).slice(0, -3) + ')');
else { day += 30; }
}
}
else { $ele.toggleClass('error countdownNode').text( mw.msg('widget-cd-error') ); }
if (month < 0) {
year--;
});
month += 12;
const $counting = $nodes.filter( '.counting' );
if ($counting.length === 0) { return; }
}
console.log('Hook: wikipage.content,开始添加倒计时');
if (year > 0) { result += `<span class="countdown-num">${year}</span>年`; }
run();
if (month > 0 || result !== "") { result += `<span class="countdown-num">${month}</span>${textMonth}`; }
$counting.removeClass( 'countdownNode' ); // 新节点至少要执行过一次run()后才能移除countdownNode类
if (day > 0 || result !== "") { result += `<span class="countdown-num">${day}</span>天`; }
counter = counter || setInterval(run, 1000); // 防止重复setInterval
if (year === 0 && month === 0) {
if (hour > 0 || result !== "") { result += `<span class="countdown-num">${hour}</span>${textHour}`; }
if (day === 0) {
if (minute > 0 || result !== "") { result += `<span class="countdown-num">${minute}</span>分`; }
if (second > 0 || result !== "") { result += `<span class="countdown-num">${second}</span>秒`; }
}
}
if (isBefore) {
const countdown = before.querySelector( '.countdown' );
if (countdown) { countdown.innerHTML = result; }
before.style.display = "";
after.style.display = "none";
}
else {
const countdown = after.querySelector( '.countdown' );
if (countdown) { countdown.innerHTML = result; }
after.style.display = "";
before.style.display = "none";
}
}
function run(mw) {
document.querySelectorAll( '.countdownNode' ).each(ele => {
fromNow(ele, mw);
ele.classList.add( 'counting' );
});
});
}
},
handler = () => {

$num = $('<span>', {class: 'countdown-num'});
document.querySelectorAll( '.countdownNode' ).forEach(ele => {
// 补齐2位数日期
mw.widget = mw.widget || {};
if (mw.widget.countdown) { return; } // 不要和mw.countdown搞混
const target = ele.dataset.target.replace( /-(\d)(?=\D)/g, '-0$1' ).replace( /-(\d)$/, '-0$1' ),
mw.hook( 'wikipage.content' ).add( main );
time = new Date(target);
if (!time.getTime()) {
mw.widget.countdown = true;
};
ele.classList.add( "error" );
if (window.jQuery) { handler(); }
ele.textContent = "(时间格式错误!)";
else { window.addEventListener( 'jquery', handler ); }
ele.classList.remove( 'countdownNode' );
}
else { ele.dataset.target = target; }
});
console.log( 'setInterval: 等待mediaWiki加载完毕' );
const timerStart = Date.now(),
timer = setInterval(() => {
if (!window.mediaWiki) { return; }
clearInterval(timer);
console.log(`End setInterval: mediaWiki加载完毕,用时 ${Date.now() - timerStart} ms`);
run(window.mediaWiki);
setInterval( run(window.mediaWiki), 1000 );
}, 100);
}) ();
}) ();
//</nowiki>
//</nowiki>
// [[category:JavaScript小部件]] {{DEFAULTSORT:Countdown}}
// [[category:jQuery小部件]] {{DEFAULTSORT:Countdown.js}}

2021年2月10日 (三) 06:40的最新版本

//<nowiki>
// 用于[[Widget:Countdown]],可以使用ES6语法
/**
 * @Function: 生成倒计时
 * @Source: [[moegirl:Widget:Countdown]]
 * @Dependencies: moment, ext.gadget.site-lib
 * @EditedBy: [[User:Bhsd]]
 */
"use strict";
/*global mw, $, moment, wgUCS*/
(() => {
    let counter, $num;
    const fromNow = function() { // 处理一个 .counting 节点,显示时间
        const $ele = $(this),
            now = moment(), // now必须是一个新的moment对象
            then = moment( $ele.data('target') ), // 必需复制一个moment对象再进行操作
            isBefore = then.isBefore( now ),
            [early, late] = isBefore ? [then, now] : [now, then],
            year = late.diff( early, 'year' ),
            month = late.diff( early.add(year, 'year'), 'month' ),
            day = year ? null : late.diff( early.add(month, 'month'), 'day' ),
            hour = year || month ? null : late.diff( early.add(day, 'day'), 'hour' ),
            minute = year || month || day ? null : late.diff( early.add(hour, 'hour'), 'minute' ),
            second = year || month || day ? null : late.diff( early.add(minute, 'minute'), 'second' ),
            result = [
            ... year ? [$num.clone().text( year ), '年'] : [],
            ... month ? [$num.clone().text( month ), mw.msg('widget-cd-mm')] : [],
            ... day ? [$num.clone().text( day ), '天'] : [],
            ... hour ? [$num.clone().text( hour ), mw.msg('widget-cd-hh')] : [],
            ... minute !== null ? [$num.clone().text( minute ), '分'] : [],
            ... second !== null ? [$num.clone().text( second ), '秒'] : []
        ];
        $ele.toggleClass('isBefore', isBefore).children().eq(isBefore ? 0 : 1).find( '.countdown' ).html( result );
    },
        run = () => { $( '.counting' ).each( fromNow ); }, // 每秒循环一遍所有 .counting 节点
        main = ($content) => {
        const $nodes = $content.find( '.countdownNode' );
        if ($nodes.length === 0) { return; }
        mw.loader.using( ['moment', 'ext.gadget.site-lib'] ).then(() => {
            mw.messages.set( wgUCS({ 'widget-cd-error': "时间格式错误!", 'widget-cd-mm': '个月', 'widget-cd-hh': '小时' },
               { 'widget-cd-error': "時間格式錯誤!", 'widget-cd-mm': '個月', 'widget-cd-hh': '小時' }) );
            $nodes.each(function() {
                const $ele = $(this),
                    then = moment(this.title, 'YYYY-MM-DD HH:mm Z');
                if (then.isValid()) {
                    $ele.data('target', then).addClass( 'counting' )
                         // 以本地时间替换title,之后交给[[Widget:Abbr]]就好
                        .attr('title', then.format( 'llll ([UTC]Z' ).slice(0, -3) + ')');
                }
                else { $ele.toggleClass('error countdownNode').text( mw.msg('widget-cd-error') ); }
            });
            const $counting = $nodes.filter( '.counting' );
            if ($counting.length === 0) { return; }
            console.log('Hook: wikipage.content,开始添加倒计时');
            run();
            $counting.removeClass( 'countdownNode' ); // 新节点至少要执行过一次run()后才能移除countdownNode类
            counter = counter || setInterval(run, 1000); // 防止重复setInterval
        });
    },
        handler = () => {
        $num = $('<span>', {class: 'countdown-num'});
        mw.widget = mw.widget || {};
        if (mw.widget.countdown) { return; } // 不要和mw.countdown搞混
        mw.hook( 'wikipage.content' ).add( main );
        mw.widget.countdown = true;
    };
    if (window.jQuery) { handler(); }
    else { window.addEventListener( 'jquery', handler ); }
}) ();
//</nowiki>
// [[category:jQuery小部件]] {{DEFAULTSORT:Countdown.js}}