打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

MediaWiki:Common.js:修订间差异

MediaWiki界面页面
卡介菌
卡介菌留言 | 贡献 (改监听条件)
第177行: 第177行:
              
              
             console.log("RizPlayer found, initializing...");
             console.log("RizPlayer found, initializing...");
             function checkScrollState() {
 
                 var isScrollDown = document.documentElement.classList.contains('citizen-scroll--down');
            var lastScrollTop = 0;
                 if (isScrollDown) {
            var scrollThreshold = 10;
 
             $(window).on('scroll resize', function() {
                 if (window.innerWidth > 768) {
                    $player.removeClass('rp-scroll-down');
                    return;
                }
 
                var st = $(this).scrollTop();
               
                if (Math.abs(lastScrollTop - st) <= scrollThreshold) return;
                 if (st > lastScrollTop && st > 50) {
                     $player.addClass('rp-scroll-down');
                     $player.addClass('rp-scroll-down');
                 } else {
                 } else {
                     $player.removeClass('rp-scroll-down');
                     $player.removeClass('rp-scroll-down');
                 }
                 }
            }
                 lastScrollTop = st;
           
            // 启动监听器
            var observer = new MutationObserver(function(mutations) {
                 mutations.forEach(function(mutation) {
                    if (mutation.attributeName === "class") {
                        checkScrollState();
                    }
                });
             });
             });
            observer.observe(document.documentElement, { attributes: true });
            checkScrollState(); // 初始化时先检查一次


             var songUrl = $player.data('url');
             var songUrl = $player.data('url');

2025年12月1日 (一) 21:29的版本

/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* JavaScript used for https://zh.wikipedia.org/wiki/MediaWiki:Common.js : */

    /** metaBox
     *
     * Funcionament de la Plantilla:Metacaixa
     * Implementat per: Usuari:Peleguer.
     * Actualitzat per Joanjoc seguint les indicacions d'en Martorell
     */
     document.querySelector('.mw-logo-wordmark').textContent=''
    function MetaCaixaInit() {
      // S'executa al carregar-se la pàgina, si hi ha metacaixes,
      // s'assignen els esdeveniments als botons
      //alert("MetaCaixaInit");
      var i = 0; // Inicialitzem comptador de caixes
      for (i = 0; i <= 9; i++) {
        var vMc = document.getElementById("mc" + i);
        if (!vMc) break;
        //alert("MetaCaixaInit, trobada Metacaixa mc"+i);
        var j = 1; // Inicialitzem comptador de botons dins de la caixa
        var vPsIni = 0; // Pestanya visible inicial
        for (j = 1; j <= 9; j++) {
          var vBt = document.getElementById("mc" + i + "bt" + j);
          if (!vBt) break;
          //alert("MetaCaixaInit, trobat botó mc"+i+"bt"+j);
          vBt.onclick = MetaCaixaMostraPestanya; // A cada botó assignem l'esdeveniment onclick
          //alert (vBt.className);
          if (vBt.className == "mcBotoSel") vPsIni = j; // Si tenim un botó seleccionat, en guardem l'index
        }
        //alert ("mc="+i+", ps="+j+", psini="+vPsIni );
        if (vPsIni === 0) { // Si no tenim cap botó seleccionat, n'agafem un aleatòriament
          vPsIni = 1 + Math.floor((j - 1) * Math.random());
          //alert ("Activant Pestanya a l'atzar; _mc"+i+"bt"+vPsIni +"_");
          document.getElementById("mc" + i + "ps" + vPsIni).style.display = "block";
          document.getElementById("mc" + i + "ps" + vPsIni).style.visibility = "visible";
          document.getElementById("mc" + i + "bt" + vPsIni).className = "mcBotoSel";
        }
      }
    }

    function MetaCaixaMostraPestanya() {
      // S'executa al clicar una pestanya,
      // aquella es fa visible i les altres s'oculten
      var vMcNom = this.id.substr(0, 3); // A partir del nom del botó, deduïm el nom de la caixa
      var vIndex = this.id.substr(5, 1); // I l'index
      var i = 1;
      for (i = 1; i <= 9; i++) { // busquem totes les pestanyes d'aquella caixa
        //alert(vMcNom+"ps"+i);
        var vPsElem = document.getElementById(vMcNom + "ps" + i);
        if (!vPsElem) break;
        if (vIndex == i) { // Si és la pestanya bona la mostrem i canviem la classe de botó
          vPsElem.style.display = "block";
          vPsElem.style.visibility = "visible";
          document.getElementById(vMcNom + "bt" + i).className = "mcBotoSel";
        } else { // Sinó, l'ocultem i canviem la classe de botó
          vPsElem.style.display = "none";
          vPsElem.style.visibility = "hidden";
          document.getElementById(vMcNom + "bt" + i).className = "mcBoto";
        }
      }
      return false; // evitem la recàrrega de la pàgina
    }
    $(MetaCaixaInit);
    
 //BMV模板script
 (function(mw, $) {
    'use strict';

    function initBmvPlayer(wrapper) {
        var $wrapper = $(wrapper);
        
        var songName = $wrapper.data('song-name');
        var rawDifficulties = $wrapper.data('difficulties');

        var $difficultyDiv = $wrapper.find('.difficulty-div');
        var $ratioDiv = $wrapper.find('.ratio-div');
        var $outputSpan = $wrapper.find('.output-span');
        
        var difficultyColors = {
            "EZ": "#57E4C4", "HD": "#FDBA61", "IN": "#FE8661", "AT": "#4C364B"
        };

        function parseDifficulties(input) {
            if (!input) return null;
            try {
                return input.split(',').map(function(item) {
                    var match = item.trim().match(/^([A-Za-z]+)([\d]+[+-]?)$/); 
                    if (!match) {
                        throw new Error('Invalid difficulty format for item: ' + item);
                    }
                    return (match[1].toUpperCase() + ' ' + match[2]);
                });
            } catch (e) {
                console.error("Error parsing difficulties:", input, e);
                return null;
            }
        }


        var difficultyStates = parseDifficulties(rawDifficulties);

        if (!songName || !difficultyStates || difficultyStates.length === 0) {
            $wrapper.find('table').html('<div style="color:red; padding:10px; text-align:center;">错误: 缺少或无效的曲名/难度参数。</div>');
            return;
        }

        $difficultyDiv.attr('data-states', JSON.stringify(difficultyStates));

        function updateOutput() {
            var difficulty = $difficultyDiv.text().split(' ')[0];
            var ratio = $ratioDiv.text().replace(':', '-');
            var processedSongName = songName.replace(/[\\/:\*\?"<>\|]/g, '-');
            var encodedSongName = encodeURIComponent(processedSongName);
            var videoUrl = 'https://pan.rizwiki.cn/d/' + ratio + '_' + encodedSongName + '_' + difficulty + '.mp4';
            var isMobile = window.matchMedia("(max-width: 600px)").matches;
            var videoHeightStyle = isMobile ? '' : 'height:100%;';
            $outputSpan.html('<video class="html5media-video" src="' + videoUrl + '" controls preload="metadata" loading="lazy" style="' + videoHeightStyle + ' object-fit:contain;"></video>');
        }

        function cycleDifficulty() {
            var states = JSON.parse($difficultyDiv.attr('data-states'));
            var current = parseInt($difficultyDiv.attr('data-current'), 10);
            current = (current + 1) % states.length;
            
            var nextState = states[current];
            $difficultyDiv.text(nextState);
            $difficultyDiv.attr('data-current', current.toString());
            
            var difficultyType = nextState.split(' ')[0];
            $difficultyDiv.parent().css('background-color', difficultyColors[difficultyType] || '#FFFFFF');
            
            updateOutput();
        }

        function cycleRatio() {
            var states = JSON.parse($ratioDiv.attr('data-states'));
            var current = parseInt($ratioDiv.attr('data-current'), 10);
            current = (current + 1) % states.length;
            
            $ratioDiv.text(states[current]);
            $ratioDiv.attr('data-current', current.toString());
            
            updateOutput();
        }

        $difficultyDiv.on('click', cycleDifficulty);
        $ratioDiv.parent().on('click', cycleRatio);

        // 初始化
        (function initialize() {
            var firstDiff = difficultyStates[0];
            var diffType = firstDiff.split(' ')[0];
            
            $difficultyDiv.text(firstDiff);
            $difficultyDiv.parent().css('background-color', difficultyColors[diffType]);
            
            updateOutput();
        })();
    }

    mw.hook('wikipage.content').add(function($content) {
        // 初始化 BMV 播放器
        $content.find('.bmv-player-uninitialized').each(function() {
            initBmvPlayer(this);
            $(this).removeClass('bmv-player-uninitialized');
        });

/* 绿豆诡计播放器js */
        var $player = $('#riz-player');
        if ($player.length > 0) {
            if ($player.parent().is('body') === false) {
                $player.appendTo('body');
            }

            if ($player.data('initialized')) return;
            $player.data('initialized', true);
            
            console.log("RizPlayer found, initializing...");

            var lastScrollTop = 0;
            var scrollThreshold = 10;

            $(window).on('scroll resize', function() {
                if (window.innerWidth > 768) {
                    $player.removeClass('rp-scroll-down');
                    return;
                }

                var st = $(this).scrollTop();
                
                if (Math.abs(lastScrollTop - st) <= scrollThreshold) return;
                if (st > lastScrollTop && st > 50) {
                    $player.addClass('rp-scroll-down');
                } else {
                    $player.removeClass('rp-scroll-down');
                }
                lastScrollTop = st;
            });

            var songUrl = $player.data('url');
            if (!songUrl) {
                console.error("RizPlayer Error: No audio URL found.");
                return;
            }

            // 封面图修复逻辑
            var $coverImg = $player.find('.rp-cover-img');
            if ($coverImg.length === 0) $coverImg = $player.find('.rp-cover img');
            
            var backupSrc = $player.data('image');
            
            function fixCoverImage() {
                var currentSrc = $coverImg.attr('src');
                if ((!currentSrc || currentSrc === "" || currentSrc === "undefined") && backupSrc) {
                    console.log("修复封面图,使用 data-image:", backupSrc);
                    $coverImg.attr('src', backupSrc);
                }
            }
            fixCoverImage();

            var audio = new Audio(songUrl);
            audio.preload = "none";

            // 获取元素
            var $toggleBtn = $player.find('.rp-btn-toggle');
            var $sideBtn = $player.find('.rp-side-ctrl');
            var $progressWrap = $player.find('.rp-progress-wrap');
            var $progressBar = $player.find('.rp-progress-bar');
            var $progressCurrent = $player.find('.rp-progress-current');
            var $progressHandle = $player.find('.rp-progress-handle');
            var $curTime = $player.find('.rp-cur');
            var $durTime = $player.find('.rp-dur');

            // 显示播放器
            $player.css('display', 'flex');

            function formatTime(seconds) {
                if (isNaN(seconds)) return "00:00";
                var m = Math.floor(seconds / 60);
                var s = Math.floor(seconds % 60);
                return (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
            }

            // 播放/暂停
            function togglePlay(e) {
                if(e) e.stopPropagation();
                if (audio.paused) {
                    var playPromise = audio.play();
                    if (playPromise !== undefined) {
                        playPromise.then(function() {
                            $player.addClass('playing');
                            if (!$player.hasClass('riz-player-expanded')) {
                                $player.addClass('riz-player-expanded');
                            }
                        }).catch(function(error) {
                            console.error("播放失败:", error);
                        });
                    }
                } else {
                    audio.pause();
                    $player.removeClass('playing');
                }
            }

            // 绑定点击事件
            $toggleBtn.on('click', togglePlay);
            $sideBtn.on('click', togglePlay);

            // 展开/折叠
            $player.on('click', function(e) {
                if ($(e.target).closest('.rp-progress-wrap, .rp-side-ctrl, .rp-btn-toggle').length > 0) return;
                $player.toggleClass('riz-player-expanded');
            });

            var isDragging = false;

            $progressWrap.on('mousedown touchstart', function(e) {
                isDragging = true;
                $progressWrap.addClass('dragging');
                updateProgressFromEvent(e);
            });

            $(document).on('mousemove touchmove', function(e) {
                if (isDragging) {
                    e.preventDefault();
                    updateProgressFromEvent(e);
                }
            });

            $(document).on('mouseup touchend', function(e) {
                if (isDragging) {
                    isDragging = false;
                    $progressWrap.removeClass('dragging');
                    if (audio.duration) {
                        var percent = parseFloat($progressCurrent[0].style.width) / 100;
                        audio.currentTime = percent * audio.duration;
                        if(audio.paused) {
                             audio.play();
                             $player.addClass('playing');
                        }
                    }
                }
            });

            function updateProgressFromEvent(e) {
                var clientX = e.clientX;
                if (e.type.includes('touch')) {
                    clientX = e.originalEvent.touches[0].clientX;
                }
                var offset = $progressWrap.offset();
                var width = $progressWrap.width();
                var relX = clientX - offset.left;
                var percent = (relX / width) * 100;
                if (percent < 0) percent = 0;
                if (percent > 100) percent = 100;

                $progressCurrent.css('width', percent + '%');
                $progressHandle.css('left', percent + '%');
                if (audio.duration) {
                    var dragTime = (percent / 100) * audio.duration;
                    $curTime.text(formatTime(dragTime));
                }
            }

            audio.addEventListener('timeupdate', function() {
                if (!isDragging && audio.duration) {
                    var percent = (audio.currentTime / audio.duration) * 100;
                    $progressCurrent.css('width', percent + '%');
                    $progressHandle.css('left', percent + '%');
                    $curTime.text(formatTime(audio.currentTime));
                }
            });

            audio.addEventListener('loadedmetadata', function() {
                $durTime.text(formatTime(audio.duration));
            });

            audio.addEventListener('ended', function() {
                $player.removeClass('playing');
                $progressCurrent.css('width', '0%');
                $progressHandle.css('left', '0%');
            });

            audio.addEventListener('error', function(e) {
                console.error("音频加载错误:", audio.src);
            });
        }
    });

})(mediaWiki, jQuery);