跳转到内容

MediaWiki:Common.js:修订间差异

来自次元企鹅情报局百科
Admin留言 | 贡献
创建页面,内容为“这里的任何JavaScript将为所有用户在每次页面加载时加载。:​ ===== 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">关闭 ✕</but…”
 
Admin留言 | 贡献
无编辑摘要
第1行: 第1行:
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* ===== YouTube 弹窗播放器(全站) ===== */
 
 
/* ===============================================================
  🎬 PV 卡片展开系统(方案 A)
  点击卡片 → 展开/收起 PV 播放器
  =============================================================== */
window.togglePV = function(id) {
    var box = document.getElementById(id);
    if (!box) return;
 
    // 切换显示/隐藏
    if (box.style.display === "none" || box.style.display === "") {
        box.style.display = "block";
        box.scrollIntoView({ behavior: "smooth", block: "center" });
    } else {
        box.style.display = "none";
    }
};
 
 
 
/* ===============================================================
  🎥 YouTube 弹窗播放器(你的原版功能保留)
  =============================================================== */
(function () {
(function () {
   // 解析 a.pg-yt[data-yt] 或 [data-yt-id],点击后弹窗播放
   // 解析 a.pg-yt[data-yt] 或 [data-yt-id],点击后弹窗播放

2025年11月22日 (六) 08:39的版本

/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */


/* ===============================================================
   🎬 PV 卡片展开系统(方案 A)
   点击卡片 → 展开/收起 PV 播放器
   =============================================================== */
window.togglePV = function(id) {
    var box = document.getElementById(id);
    if (!box) return;

    // 切换显示/隐藏
    if (box.style.display === "none" || box.style.display === "") {
        box.style.display = "block";
        box.scrollIntoView({ behavior: "smooth", block: "center" });
    } else {
        box.style.display = "none";
    }
};



/* ===============================================================
   🎥 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();
  }
})();