MediaWiki:Gadget-AudioText.js:修订间差异
外观
![]() OctoberSama(留言 | 贡献) 小 |
![]() OctoberSama(留言 | 贡献) 小 |
||
第1行: | 第1行: | ||
// MediaWiki:Gadget-AudioText.js | // MediaWiki:Gadget-AudioText.js | ||
(function() { | (function() { | ||
// | // 强制声明依赖并确保mw.util可用 | ||
mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() { | |||
alert("🎉 JS脚本已加载!"); // 确保依赖加载完成后才提示 | |||
// 主初始化函数 | |||
function initAudioTriggers() { | |||
try { | |||
const triggers = document.querySelectorAll('.audio-trigger'); | |||
if (triggers.length === 0) { | |||
alert("⚠️ 未找到任何音频触发器元素!检查模板类名是否正确"); | |||
return; | |||
} | |||
triggers.forEach(element => { | |||
if (element._initialized) return; | |||
element._initialized = true; | |||
// | // 绑定标准化事件(兼容移动端) | ||
const | const handler = async (event) => { | ||
. | event.preventDefault(); | ||
alert("🖱️ 点击事件已触发!"); // 确保事件触发可见 | |||
await handleClick(element); | |||
}; | |||
element.addEventListener('touchstart', handler, { passive: false }); | |||
element.addEventListener('click', handler); | |||
}); | |||
} catch (error) { | |||
alert(`💥 初始化失败: ${error.message}`); | |||
} | |||
} | |||
} catch (error) { | |||
// 点击处理核心逻辑 | |||
async function handleClick(element) { | |||
try { | |||
const audioFile = element.dataset.audioFile; | |||
alert(`📁 模板参数: ${audioFile}`); | |||
// 获取音频URL | |||
const audioUrl = await getAudioUrl(audioFile); | |||
alert(`🎵 最终音频地址: ${audioUrl}`); | |||
// 立即播放不等待调试 | |||
await playAudio(audioUrl); | |||
// 延迟显示成功提示 | |||
setTimeout(() => { | |||
alert("✅ 播放成功!"); | |||
element.style.backgroundColor = "#e6ffe6"; | |||
setTimeout(() => element.style.backgroundColor = "", 1000); | |||
}, 300); | |||
} catch (error) { | |||
alert(`❌ 播放失败: ${error.message}`); | |||
element.style.backgroundColor = "#ffe6e6"; | |||
setTimeout(() => element.style.backgroundColor = "", 1000); | |||
} | |||
} | |||
// 获取音频URL(带重试机制) | |||
async function getAudioUrl(audioFile) { | |||
try { | |||
const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' + | |||
encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json'; | |||
const response = await fetch(apiUrl); | |||
if (!response.ok) throw new Error(`API返回${response.status}状态`); | |||
const data = await response.json(); | |||
const pages = data.query.pages; | |||
const pageId = Object.keys(pages)[0]; | |||
if (!pages[pageId].imageinfo) { | |||
throw new Error("文件不存在或无查看权限"); | |||
} | |||
return pages[pageId].imageinfo[0].url; | |||
} catch (error) { | |||
throw new Error(`获取URL失败: ${error.message}`); | |||
} | |||
} | |||
// 专用播放器(兼容iOS) | |||
async function playAudio(url) { | |||
try { | |||
// iOS特殊处理 | |||
if (/iPad|iPhone|iPod/.test(navigator.userAgent)) { | |||
const emptyAudio = new Audio(); | |||
await emptyAudio.play().catch(() => {}); | |||
} | } | ||
const audio = new Audio(url); | |||
await audio.play(); | |||
} catch (error) { | |||
throw new Error(`浏览器阻止播放: ${error.message}`); | |||
}); | } | ||
} | |||
// 双重初始化保障 | |||
mw.hook('wikipage.content').add(initAudioTriggers); | |||
if (document.readyState === 'complete') { | |||
initAudioTriggers(); | |||
} else { | |||
document.addEventListener('DOMContentLoaded', initAudioTriggers); | |||
} | |||
}).catch(error => { | |||
alert(`💣 核心依赖加载失败: ${error.message}`); | |||
}); | |||
})(); | })(); |
2025年5月24日 (六) 22:42的版本
// MediaWiki:Gadget-AudioText.js (function() { // 强制声明依赖并确保mw.util可用 mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() { alert("🎉 JS脚本已加载!"); // 确保依赖加载完成后才提示 // 主初始化函数 function initAudioTriggers() { try { const triggers = document.querySelectorAll('.audio-trigger'); if (triggers.length === 0) { alert("⚠️ 未找到任何音频触发器元素!检查模板类名是否正确"); return; } triggers.forEach(element => { if (element._initialized) return; element._initialized = true; // 绑定标准化事件(兼容移动端) const handler = async (event) => { event.preventDefault(); alert("🖱️ 点击事件已触发!"); // 确保事件触发可见 await handleClick(element); }; element.addEventListener('touchstart', handler, { passive: false }); element.addEventListener('click', handler); }); } catch (error) { alert(`💥 初始化失败: ${error.message}`); } } // 点击处理核心逻辑 async function handleClick(element) { try { const audioFile = element.dataset.audioFile; alert(`📁 模板参数: ${audioFile}`); // 获取音频URL const audioUrl = await getAudioUrl(audioFile); alert(`🎵 最终音频地址: ${audioUrl}`); // 立即播放不等待调试 await playAudio(audioUrl); // 延迟显示成功提示 setTimeout(() => { alert("✅ 播放成功!"); element.style.backgroundColor = "#e6ffe6"; setTimeout(() => element.style.backgroundColor = "", 1000); }, 300); } catch (error) { alert(`❌ 播放失败: ${error.message}`); element.style.backgroundColor = "#ffe6e6"; setTimeout(() => element.style.backgroundColor = "", 1000); } } // 获取音频URL(带重试机制) async function getAudioUrl(audioFile) { try { const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' + encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json'; const response = await fetch(apiUrl); if (!response.ok) throw new Error(`API返回${response.status}状态`); const data = await response.json(); const pages = data.query.pages; const pageId = Object.keys(pages)[0]; if (!pages[pageId].imageinfo) { throw new Error("文件不存在或无查看权限"); } return pages[pageId].imageinfo[0].url; } catch (error) { throw new Error(`获取URL失败: ${error.message}`); } } // 专用播放器(兼容iOS) async function playAudio(url) { try { // iOS特殊处理 if (/iPad|iPhone|iPod/.test(navigator.userAgent)) { const emptyAudio = new Audio(); await emptyAudio.play().catch(() => {}); } const audio = new Audio(url); await audio.play(); } catch (error) { throw new Error(`浏览器阻止播放: ${error.message}`); } } // 双重初始化保障 mw.hook('wikipage.content').add(initAudioTriggers); if (document.readyState === 'complete') { initAudioTriggers(); } else { document.addEventListener('DOMContentLoaded', initAudioTriggers); } }).catch(error => { alert(`💣 核心依赖加载失败: ${error.message}`); }); })();