用户:卡介菌/common.js
来自Rizline中文维基
更多操作
< 用户:卡介菌
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5。
mw.loader.using(['mediawiki.util', 'jquery']).done(function() {
$(function() {
// 寻找所有使用了这个模板的容器,并对每一个分别进行处理
$('.bmv-container').each(function() {
const container = $(this);
// 从 data-* 属性获取模板参数
const songName = container.data('song-name');
const rawDifficulties = container.data('difficulties');
// 在当前容器内查找元素
const difficultyDiv = container.find('.bmv-difficulty-btn');
const ratioDiv = container.find('.bmv-ratio-btn');
const outputSpan = container.find('.bmv-output');
// 难度颜色映射
const difficultyColors = {
"EZ": "#57E4C4",
"HD": "#FDBA61",
"IN": "#FE8661",
"AT": "#4C364B"
};
// 解析并设置难度数据
function parseDifficulties(input) {
if (!input || typeof input !== 'string') return null;
try {
// 使用更健壮的正则匹配,允许难度和等级之间有或没有空格
return input.split(',').map(item => {
const match = item.trim().match(/^([A-Za-z]+)\s*(\d+)$/);
if (!match) throw new Error('Invalid format');
return `${match[1].toUpperCase()} ${match[2]}`;
});
} catch (e) {
console.error("解析难度参数时出错(Error parsing difficulties):", input, e);
return null;
}
}
const difficultyStates = parseDifficulties(rawDifficulties);
// 检查参数是否有效
if (!songName || !difficultyStates || difficultyStates.length === 0) {
// 在容器内显示错误信息,而不是替换整个表格
container.css('text-align', 'center').html('<div style="color:red; padding:20px; font-weight:bold;">模板错误:缺少或无效的 songName/difficulties 参数。</div>');
return; // 跳过这个容器实例的处理
}
// 将解析后的难度数据设置到元素上
difficultyDiv.attr('data-states', JSON.stringify(difficultyStates));
// 更新视频输出
function updateOutput() {
const difficulty = difficultyDiv.text().split(' ')[0];
const ratio = ratioDiv.text().replace(':', '-');
const encodedSongName = encodeURIComponent(songName);
const videoUrl = `https://pan.rizwiki.cn/d/${ratio}_${encodedSongName}_${difficulty}.mp4`;
// 使用 jQuery 创建 video 元素,更安全
const videoElement = $('<video>', {
class: 'html5media-video',
src: videoUrl,
controls: true,
preload: 'metadata',
loading: 'lazy',
style: 'height:100%; width:100%; object-fit:contain;'
});
outputSpan.html(videoElement);
}
// 切换难度
function cycleDifficulty() {
const states = JSON.parse(difficultyDiv.attr('data-states'));
let current = parseInt(difficultyDiv.attr('data-current'), 10);
current = (current + 1) % states.length;
const nextState = states[current];
const difficultyType = nextState.split(' ')[0];
const color = difficultyColors[difficultyType] || '#FFFFFF';
difficultyDiv.text(nextState).attr('data-current', current);
difficultyDiv.parent().css('background-color', color); // 注意这里是父元素td
updateOutput();
}
// 切换宽高比
function cycleRatio() {
const states = JSON.parse(ratioDiv.attr('data-states'));
let current = parseInt(ratioDiv.attr('data-current'), 10);
current = (current + 1) % states.length;
ratioDiv.text(states[current]).attr('data-current', current);
updateOutput();
}
// 绑定事件
difficultyDiv.on('click', cycleDifficulty);
ratioDiv.parent().on('click', cycleRatio); // 绑定到父元素td上
// 初始化
function initialize() {
const firstDiff = difficultyStates[0];
const diffType = firstDiff.split(' ')[0];
difficultyDiv.text(firstDiff);
difficultyDiv.parent().css('background-color', difficultyColors[diffType]);
updateOutput();
}
initialize();
});
});
});