打开/关闭搜索
搜索
打开/关闭菜单
228
885
35
2802
植物大战僵尸杂交版Wiki
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
上传文件
打开/关闭外观设置菜单
notifications
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
查看“︁MediaWiki:Common.js”︁的源代码
MediaWiki界面页面
查看
阅读
查看源代码
查看历史
associated-pages
系统消息
讨论
更多操作
←
MediaWiki:Common.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */ // 自动加载 MediaWiki:Footer 页面内容,并插入到每个页面底部 $(document).ready(function() { const namespace = mw.config.get('wgNamespaceNumber'); const action = mw.config.get('wgAction'); if (namespace !== 0 || action !== 'view') { return; } fetch("/api.php?action=parse&page=MediaWiki:Footer&format=json") .then(res => res.json()) .then(data => { if (data.parse && data.parse.text) { const html = data.parse.text['*']; $('#mw-content-text').append('<div class="global-footer">' + html + '</div>'); } }); }); $(function () { // ==================== 动态注入彩虹样式(无星星伪元素) ==================== var rainbowStyle = document.createElement('style'); rainbowStyle.textContent = '.rainbow-user {' + 'font-weight: bold;' + 'background: repeating-linear-gradient(90deg, red 0px, orange 10px, yellow 20px, green 30px, blue 40px, indigo 50px, violet 60px);' + '-webkit-background-clip: text;' + '-webkit-text-fill-color: transparent;' + 'background-clip: text;' + '}'; document.head.appendChild(rainbowStyle); // ==================== 配置区 ==================== var mentorList = ['愤怒的郎朗', 'Yuyaabc','虚位以待','知更鸟头号粉丝']; // 手动配置导师用户名 var newbieEditThreshold = 25; // 编辑数 ≤ 25 自动标记为新手 // ==================== 辅助函数 ==================== function getUserName(link) { var $span = $(link).find('span').first(); if ($span.length) return $span.text().trim(); return $(link).text().trim(); } function isUserLink(link) { return $(link).is('a.mw-userlink') || $(link).find('span').length > 0; } // 计算等级图标字符串 function getLevelIcons(editcount) { var totalStars = Math.floor(editcount / 100); if (totalStars === 0) return ''; // 不够100次不显示 var crowns = Math.floor(totalStars / 125); // 5太阳 = 125星 var remaining = totalStars % 125; var suns = Math.floor(remaining / 25); // 5月亮 = 25星 remaining %= 25; var moons = Math.floor(remaining / 5); // 5星 = 1月亮 var stars = remaining % 5; var icons = ''; // 用 repeat 生成对应数量图标 if (crowns > 0) icons += '👑'.repeat(crowns); if (suns > 0) icons += '☀️'.repeat(suns); if (moons > 0) icons += '🌙'.repeat(moons); if (stars > 0) icons += '⭐'.repeat(stars); return icons; } // 更新或创建等级图标元素 function updateLevelIcons($link, editcount) { var iconStr = getLevelIcons(editcount); var $iconSpan = $link.next('.user-level-icons'); if (iconStr === '') { // 编辑数不够,移除图标 $iconSpan.remove(); return; } if ($iconSpan.length === 0) { $iconSpan = $('<span class="user-level-icons"></span>'); $link.after($iconSpan); } $iconSpan.text(iconStr); } // ==================== 核心处理流程 ==================== function colorizeAndStatus($links) { if ($links.length === 0) return; var $fresh = $links.filter(function () { return !$(this).data('user-status-processed'); }); if ($fresh.length === 0) return; var users = []; $fresh.each(function () { var name = getUserName(this); if (name && users.indexOf(name) === -1) users.push(name); }); if (users.length === 0) return; $fresh.each(function () { $(this).data('user-status-processed', true); }); // 1. 批量查询编辑数(用于颜色 + 等级图标) var batchSize = 50; var batches = []; for (var i = 0; i < users.length; i += batchSize) { batches.push(users.slice(i, i + batchSize)); } var processBatch = function (batch) { var api = new mw.Api(); return api.get({ action: 'query', list: 'users', ususers: batch.join('|'), usprop: 'editcount' }).then(function (data) { var classMap = {}; var editCountMap = {}; if (data.query && data.query.users) { data.query.users.forEach(function (u) { var ec = u.editcount || 0; editCountMap[u.name] = ec; // 颜色等级判定 if (ec >= 5000) classMap[u.name] = 'rainbow-user'; else if (ec >= 2500) classMap[u.name] = 'gold-user'; else if (ec >= 1000) classMap[u.name] = 'platinum-user'; else if (ec >= 500) classMap[u.name] = 'silver-user'; else if (ec >= 1) classMap[u.name] = 'bronze-user'; }); } // 应用颜色和等级图标 $fresh.each(function () { var $this = $(this); var name = getUserName(this); var cls = classMap[name]; if (cls) { $this.removeClass('bronze-user silver-user platinum-user gold-user rainbow-user'); $this.addClass(cls); } // 更新等级图标 var ec = editCountMap[name]; if (typeof ec !== 'undefined') { updateLevelIcons($this, ec); } }); }); }; var colorPromise = $.Deferred().resolve(); batches.forEach(function (batch) { colorPromise = colorPromise.then(function () { return processBatch(batch); }); }); // 2. 非卡片区域:状态圆点 + 师徒标签 $fresh.each(function () { if (isUserLink(this)) { var isInsideCard = $(this).closest('.citizen-menu_card-content, .citizen-userMenu').length > 0; if (!isInsideCard) { var username = getUserName(this); addStatusDot($(this), username); addMentorTag($(this), username); } } }); } // ==================== 状态圆点(不变) ==================== function addStatusDot($link, username) { if ($link.data('status-dot-added')) return; $link.data('status-dot-added', true); var $dot = $('<span class="user-status-dot status-offline" title="离线"></span>'); $link.after($dot); // 会插入在等级图标之后,无所谓顺序 var cacheKey = 'mw_user_status_' + mw.config.get('wgDBname') + '_' + username; var cached = localStorage.getItem(cacheKey); var now = Date.now(); if (cached) { try { var data = JSON.parse(cached); if (now - data.timestamp < 5 * 60 * 1000) { updateDotStyle($dot, data.lastEditTime); return; } } catch (e) {} } var api = new mw.Api(); api.get({ action: 'query', list: 'usercontribs', ucuser: username, uclimit: 1, ucprop: 'timestamp' }).then(function (data) { var lastEditTime = null; if (data.query && data.query.usercontribs && data.query.usercontribs.length > 0) { lastEditTime = data.query.usercontribs[0].timestamp; } localStorage.setItem(cacheKey, JSON.stringify({ lastEditTime: lastEditTime, timestamp: now })); updateDotStyle($dot, lastEditTime); }).fail(function () {}); } function updateDotStyle($dot, lastEditTime) { if (!lastEditTime) { $dot.attr('title', '离线'); $dot.removeClass('status-online status-away').addClass('status-offline'); return; } var last = new Date(lastEditTime).getTime(); var diffMinutes = (Date.now() - last) / 60000; if (diffMinutes < 15) { $dot.attr('title', '在线(15分钟内活跃)'); $dot.removeClass('status-offline status-away').addClass('status-online'); } else if (diffMinutes < 60) { $dot.attr('title', '近期活跃(1小时内)'); $dot.removeClass('status-offline status-online').addClass('status-away'); } else { $dot.attr('title', '离线'); $dot.removeClass('status-online status-away').addClass('status-offline'); } } // ==================== 师徒标签 ==================== function addMentorTag($link, username) { if ($link.data('mentor-tag-added')) return; if ($link.next('.user-tag').length) return; if (mentorList.indexOf(username) !== -1) { $link.data('mentor-tag-added', true); var $tag = $('<span class="user-tag user-tag-mentor">导师</span>'); $link.after($tag); return; } // 新手判定(带缓存) if ($link.data('newbie-tag-checked')) return; $link.data('newbie-tag-checked', true); var cacheKey = 'mw_newbie_check_' + mw.config.get('wgDBname') + '_' + username; var cached = localStorage.getItem(cacheKey); var now = Date.now(); if (cached) { try { var data = JSON.parse(cached); if (now - data.timestamp < 60 * 60 * 1000) { if (data.editcount <= newbieEditThreshold) { var $tag = $('<span class="user-tag user-tag-newbie">新手</span>'); $link.after($tag); } return; } } catch (e) {} } var api = new mw.Api(); api.get({ action: 'query', list: 'users', ususers: username, usprop: 'editcount' }).then(function (data) { var editcount = 0; if (data.query && data.query.users && data.query.users.length > 0) { editcount = data.query.users[0].editcount || 0; } localStorage.setItem(cacheKey, JSON.stringify({ editcount: editcount, timestamp: now })); if (editcount <= newbieEditThreshold) { if ($link.next('.user-tag-newbie').length === 0) { var $tag = $('<span class="user-tag user-tag-newbie">新手</span>'); $link.after($tag); } } }).fail(function () {}); } // ==================== 启动 ==================== var linkSelector = 'a.mw-userlink, .citizen-menu_card-content a, .citizen-userMenu a'; colorizeAndStatus($(linkSelector)); var observer = new MutationObserver(function () { colorizeAndStatus($(linkSelector)); }); observer.observe(document.body, { childList: true, subtree: true }); setInterval(function () { colorizeAndStatus($(linkSelector)); }, 3000); }); // ==================== 植物/僵尸卡片筛选 ==================== // 植物筛选(如果页面有 #pf-name) if ($('#pf-name').length) { var $cards = $('.pvzhe-card'); var $name = $('#pf-name'); var $sunMax = $('#pf-sun-max'); var $cdMax = $('#pf-cd-max'); var $type = $('#pf-type'); var $reset = $('#pf-reset'); function filterPlants() { var name = $name.val().toLowerCase(); var sunMax = parseFloat($sunMax.val()) || Infinity; var cdMax = parseFloat($cdMax.val()) || Infinity; var type = $type.val(); $cards.each(function () { var $card = $(this); // 从卡片内部名称元素获取纯文本(兼容 <span> 标签) var n = $card.find('.pvzhe-card-name').text().toLowerCase(); var sun = parseFloat($card.data('sun')) || 0; var cd = parseFloat($card.data('cooldown')) || 0; var t = ($card.data('type') || '').toString(); var show = true; if (name && n.indexOf(name) === -1) show = false; if (sun > sunMax) show = false; if (cd > cdMax) show = false; if (type) { var cardTypes = t.split(',').map(function (s) { return s.trim(); }); if (cardTypes.indexOf(type) === -1) show = false; } $card.toggleClass('hidden-card', !show); }); } $name.on('input', filterPlants); $sunMax.on('input', filterPlants); $cdMax.on('input', filterPlants); $type.on('change', filterPlants); $reset.on('click', function () { $name.val(''); $sunMax.val(''); $cdMax.val(''); $type.val(''); filterPlants(); }); } // 僵尸筛选(如果页面有 #zf-name) if ($('#zf-name').length) { var $zcards = $('.pvzhe-card'); var $zname = $('#zf-name'); var $healthMin = $('#zf-health-min'); var $speedMax = $('#zf-speed-max'); var $ztype = $('#zf-type'); var $zreset = $('#zf-reset'); function filterZombies() { var name = $zname.val().toLowerCase(); var healthMin = parseFloat($healthMin.val()) || 0; var speedMax = parseFloat($speedMax.val()) || Infinity; var type = $ztype.val(); $zcards.each(function () { var $card = $(this); var n = $card.find('.pvzhe-card-name').text().toLowerCase(); var health = parseFloat($card.data('health')) || 0; var speed = parseFloat($card.data('speed')) || 0; var t = ($card.data('type') || '').toString(); var show = true; if (name && n.indexOf(name) === -1) show = false; if (health < healthMin) show = false; if (speed > speedMax) show = false; if (type) { var cardTypes = t.split(',').map(function (s) { return s.trim(); }); if (cardTypes.indexOf(type) === -1) show = false; } $card.toggleClass('hidden-card', !show); }); } $zname.on('input', filterZombies); $healthMin.on('input', filterZombies); $speedMax.on('input', filterZombies); $ztype.on('change', filterZombies); $zreset.on('click', function () { $zname.val(''); $healthMin.val(''); $speedMax.val(''); $ztype.val(''); filterZombies(); }); } });
返回
MediaWiki:Common.js
。
查看“︁MediaWiki:Common.js”︁的源代码
MediaWiki界面页面