MediaWiki:Common.js:修订间差异
外观
无编辑摘要 |
无编辑摘要 |
||
| (未显示同一用户的2个中间版本) | |||
| 第3行: | 第3行: | ||
/* =============================================================== | /* =============================================================== | ||
🎬 PV | 🎬 PV 播放升级 v2.0(高亮 + 动态 iframe + 单例播放) | ||
=============================================================== */ | =============================================================== */ | ||
window.togglePV = function(id) { | window.togglePV = function(id, yt) { | ||
var | var currentPlayer = document.getElementById(id); | ||
var currentCard = document.querySelector('[data-pv="' + id + '"]'); | |||
// | // 关闭所有播放器 + 去掉所有高亮 | ||
document.querySelectorAll('.pv-player').forEach(function(box) { | |||
box.style.display = "none"; | box.style.display = "none"; | ||
box.innerHTML = ""; | |||
box.dataset.open = "0"; | |||
}); | |||
document.querySelectorAll('.pv-card').forEach(function(card) { | |||
card.classList.remove('active'); | |||
}); | |||
// 如果当前已经是打开状态 → 折叠退出 | |||
if (currentPlayer.dataset.open === "1") { | |||
currentPlayer.dataset.open = "0"; | |||
return; | |||
} | |||
// 否则 → 展开当前播放器 | |||
currentPlayer.style.display = "block"; | |||
currentPlayer.dataset.open = "1"; | |||
// 当前卡片加高亮 | |||
if (currentCard) { | |||
currentCard.classList.add('active'); | |||
} | } | ||
// 写入 iframe(YouTube 原生格式) | |||
const iframe = document.createElement('iframe'); | |||
iframe.width = "100%"; | |||
iframe.height = "540"; | |||
iframe.src = "https://www.youtube.com/embed/" + yt + "?autoplay=1&rel=0&modestbranding=1&playsinline=1"; | |||
iframe.title = "YouTube Player"; | |||
iframe.frameBorder = "0"; | |||
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"; | |||
iframe.referrerPolicy = "strict-origin-when-cross-origin"; | |||
iframe.allowFullscreen = true; | |||
currentPlayer.appendChild(iframe); | |||
// 滚动到播放器位置 | |||
currentPlayer.scrollIntoView({ | |||
behavior: "smooth", | |||
block: "center" | |||
}); | |||
}; | |||
/* =============================================================== | /* =============================================================== | ||
2025年11月22日 (六) 12:44的最新版本
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* ===============================================================
🎬 PV 播放升级 v2.0(高亮 + 动态 iframe + 单例播放)
=============================================================== */
window.togglePV = function(id, yt) {
var currentPlayer = document.getElementById(id);
var currentCard = document.querySelector('[data-pv="' + id + '"]');
// 关闭所有播放器 + 去掉所有高亮
document.querySelectorAll('.pv-player').forEach(function(box) {
box.style.display = "none";
box.innerHTML = "";
box.dataset.open = "0";
});
document.querySelectorAll('.pv-card').forEach(function(card) {
card.classList.remove('active');
});
// 如果当前已经是打开状态 → 折叠退出
if (currentPlayer.dataset.open === "1") {
currentPlayer.dataset.open = "0";
return;
}
// 否则 → 展开当前播放器
currentPlayer.style.display = "block";
currentPlayer.dataset.open = "1";
// 当前卡片加高亮
if (currentCard) {
currentCard.classList.add('active');
}
// 写入 iframe(YouTube 原生格式)
const iframe = document.createElement('iframe');
iframe.width = "100%";
iframe.height = "540";
iframe.src = "https://www.youtube.com/embed/" + yt + "?autoplay=1&rel=0&modestbranding=1&playsinline=1";
iframe.title = "YouTube Player";
iframe.frameBorder = "0";
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
iframe.referrerPolicy = "strict-origin-when-cross-origin";
iframe.allowFullscreen = true;
currentPlayer.appendChild(iframe);
// 滚动到播放器位置
currentPlayer.scrollIntoView({
behavior: "smooth",
block: "center"
});
};
/* ===============================================================
🎥 YouTube 弹窗播放器(你的原版功能保留)
=============================================================== */
(function () {
// 解析 a.pg-yt[data-yt] 或 [data-yt-id],点击后弹窗播放
function buildOverlay() {
const wrap = document.createElement('div');
wrap.className = 'pg-yt-overlay';
wrap.innerHTML = [
'<div class="pg-yt-modal">',
' <button class="pg-yt-close" aria-label="Close">关闭 ✕</button>',
' <div class="pg-yt-frame"></div>',
'</div>'
].join('');
document.body.appendChild(wrap);
return wrap;
}
function ytIdFrom(urlOrId) {
if (!urlOrId) return null;
// 已是纯 ID
if (/^[A-Za-z0-9_-]{11}$/.test(urlOrId)) return urlOrId;
try {
const u = new URL(urlOrId, location.href);
// youtu.be/ID
if (u.hostname.includes('youtu.be')) return u.pathname.split('/')[1] || null;
// youtube.com/watch?v=ID
if (u.searchParams.get('v')) return u.searchParams.get('v');
// youtube.com/shorts/ID
const parts = u.pathname.split('/');
const i = parts.findIndex(p => p === 'shorts');
if (i >= 0 && parts[i+1]) return parts[i+1];
} catch(e) {}
return null;
}
function openOverlay(id, opts) {
const overlay = document.querySelector('.pg-yt-overlay') || buildOverlay();
const frameBox = overlay.querySelector('.pg-yt-frame');
const params = new URLSearchParams({
autoplay: '1',
modestbranding: '1',
rel: '0',
playsinline: '1'
});
if (opts && opts.start) params.set('start', String(opts.start));
const src = 'https://www.youtube.com/embed/' + id + '?' + params.toString();
frameBox.innerHTML = '<iframe width="100%" height="100%" src="'+src+'" title="YouTube player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>';
overlay.classList.add('active');
document.documentElement.style.overflow = 'hidden';
}
function closeOverlay() {
const overlay = document.querySelector('.pg-yt-overlay');
if (!overlay) return;
overlay.classList.remove('active');
const frameBox = overlay.querySelector('.pg-yt-frame');
frameBox.innerHTML = ''; // 停止视频
document.documentElement.style.overflow = '';
}
function wireEvents() {
// 委托点击
document.addEventListener('click', function (e) {
const a = e.target.closest('a.pg-yt, button.pg-yt, .pg-yt-thumb');
if (!a) return;
const raw = a.getAttribute('data-yt') || a.getAttribute('data-yt-id') || a.href;
const id = ytIdFrom(raw);
if (!id) return; // 非合法链接则放行
e.preventDefault();
const start = a.getAttribute('data-yt-start');
openOverlay(id, { start: start ? parseInt(start, 10) : undefined });
});
document.addEventListener('click', function (e) {
if (e.target.classList.contains('pg-yt-overlay') ||
e.target.classList.contains('pg-yt-close')) {
closeOverlay();
}
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') closeOverlay();
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', wireEvents);
} else {
wireEvents();
}
})();