MediaWiki:Common.js:修订间差异
小 尝试增加针对移动端的紧凑模式识别 标签:已被回退 |
小 修正尺寸切换逻辑 标签:已被回退 |
||
| 第31行: | 第31行: | ||
// logo 切换逻辑 | // logo 切换逻辑 | ||
// Common.js - footer logo | // Common.js - footer logo 切换逻辑(支持 dark/light + compact/normal + Citizen) | ||
$(function () { | $(function () { | ||
// ====================== | // ====================== | ||
| 第37行: | 第37行: | ||
// ====================== | // ====================== | ||
// | // 获取当前主题:dark / light | ||
function getEffectiveTheme() { | function getEffectiveTheme() { | ||
const cls = document.documentElement.classList; | |||
if (cls.contains('skin-theme-clientpref-night')) return 'dark'; | if (cls.contains('skin-theme-clientpref-night')) return 'dark'; | ||
if (cls.contains('skin-theme-clientpref-day')) return 'light'; | if (cls.contains('skin-theme-clientpref-day')) return 'light'; | ||
if (cls.contains('skin-theme-clientpref-os')) { | if (cls.contains('skin-theme-clientpref-os')) { | ||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) | if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark'; | ||
return 'light'; | return 'light'; | ||
} | } | ||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark'; | |||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) | |||
return 'light'; | return 'light'; | ||
} | } | ||
// | // 判断是否小屏(compact) | ||
function isCompactMode() { | function isCompactMode() { | ||
return window.matchMedia && window.matchMedia('(max-width: 500px)').matches; | return window.matchMedia && window.matchMedia('(max-width: 500px)').matches; | ||
} | } | ||
// | // 设置 <img> src | ||
function | function setImgSrc($img, src) { | ||
if ($img.length) $img.attr('src', src); | |||
if ($ | } | ||
// 设置 <source> srcset | |||
function setSourceSrcset($source, srcset) { | |||
if ($source.length) $source.attr('srcset', srcset); | |||
} | } | ||
| 第73行: | 第69行: | ||
// ====================== | // ====================== | ||
function updateLogos() { | function updateLogos() { | ||
const theme = getEffectiveTheme(); | |||
const compact = isCompactMode(); | |||
// 尺寸逻辑:大屏用 source 横版,宽度 88x31;小屏 fallback img 用 25x25 | |||
// 注意:compact 状态下实际用 img,小屏时尺寸固定为 25x25 | |||
const sizeNormal = { width: 88, height: 31 }; | |||
const sizeCompact = { width: 25, height: 25 }; | |||
// ---------------------- | |||
// 公共 Logo | |||
// ---------------------- | |||
['copyright', 'poweredby', 'poweredbysmw'].forEach(id => { | |||
const $li = $(`#footer-${id}ico`); | |||
if (!$li.length) return; | |||
const $picture = $li.find('picture'); | |||
if (!$picture.length) return; | |||
const $source = $picture.find('source'); | |||
const $img = $picture.find('img'); | |||
// 构造文件名 | |||
let baseName = ''; | |||
switch(id) { | |||
case 'copyright': baseName = 'cc-by-nc-sa'; break; | |||
case 'poweredby': baseName = 'poweredby-mediawiki'; break; | |||
case 'poweredbysmw': baseName = 'poweredby-smw'; break; | |||
} | |||
const normalFile = `/resources/assets/${baseName}${theme === 'dark' ? '-dark' : ''}.svg`; | |||
const compactFile = `/resources/assets/${baseName}-compact${theme === 'dark' ? '-dark' : ''}.svg`; | |||
// 设置 source -> 大屏横版 | |||
setSourceSrcset($source, normalFile); | |||
$source.attr('width', sizeNormal.width); | |||
$source.attr('height', sizeNormal.height); | |||
// 设置 img -> 小屏紧凑版 | |||
setImgSrc($img, compactFile); | |||
$img.attr('width', sizeCompact.width); | |||
$img.attr('height', sizeCompact.height); | |||
}); | |||
// Citizen | // ---------------------- | ||
// Citizen 专属 | |||
// ---------------------- | |||
if (document.body.classList.contains('skin-Citizen')) { | if (document.body.classList.contains('skin-Citizen')) { | ||
const $li = $('#footer-poweredbycitizenico'); | |||
if ($li.length) { | |||
const $picture = $li.find('picture'); | |||
const $img = $picture.length ? $picture.find('img') : $li.find('img'); | |||
const normalFile = `/resources/assets/poweredby-citizen${theme === 'dark' ? '-dark' : ''}.svg`; | |||
const compactFile = `/resources/assets/poweredby-citizen-compact${theme === 'dark' ? '-dark' : ''}.svg`; | |||
if ($picture.length) { | |||
const $source = $picture.find('source'); | |||
setSourceSrcset($source, normalFile); | |||
$source.attr('width', sizeNormal.width); | |||
$source.attr('height', sizeNormal.height); | |||
} | |||
setImgSrc($img, compactFile); | |||
$img.attr('width', sizeCompact.width); | |||
$img.attr('height', sizeCompact.height); | |||
} | |||
} | } | ||
} | } | ||
| 第99行: | 第140行: | ||
// 触发时机 | // 触发时机 | ||
// ====================== | // ====================== | ||
updateLogos(); | updateLogos(); | ||
// 监听 <html> class 变化(主题切换) | // 监听 <html> class 变化(主题切换) | ||
new MutationObserver(() => updateLogos()).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); | |||
// 监听 body DOM | // 监听 body DOM 变动(footer 异步插入) | ||
new MutationObserver(() => updateLogos()).observe(document.body, { childList: true, subtree: true }); | |||
// | // 监听系统主题 & 屏幕宽度变化 | ||
if (window.matchMedia) { | if (window.matchMedia) { | ||
const mqDark = window.matchMedia('(prefers-color-scheme: dark)'); | |||
if ( | const mqCompact = window.matchMedia('(max-width: 500px)'); | ||
if (mqDark.addEventListener) mqDark.addEventListener('change', updateLogos); | |||
else if (mqDark.addListener) mqDark.addListener(updateLogos); | |||
if (mqCompact.addEventListener) mqCompact.addEventListener('change', updateLogos); | |||
else if (mqCompact.addListener) mqCompact.addListener(updateLogos); | |||
if ( | |||
} | } | ||
// MediaWiki hook | // MediaWiki hook | ||
if (window.mw && mw.hook) | if (window.mw && mw.hook) mw.hook('user.preferencesSaved').add(updateLogos); | ||
// | // 兜底 | ||
$(window).on('load', updateLogos); | $(window).on('load', updateLogos); | ||
setTimeout(updateLogos, 1500); | setTimeout(updateLogos, 1500); | ||
}); | }); | ||
// 移除深色模式反馈提示 | // 移除深色模式反馈提示 | ||