MediaWiki:Common.js
来自勿忘草与永远的少女
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer或Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:按 Ctrl-F5。
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
$(function() {
// 检查是否已存在导航栏,避免重复添加
if ($('.fixed-top-nav').length === 0) {
// 导航栏 HTML 结构
var navHtml = `
<div class="fixed-top-nav">
<a href="首页" class="nav-logo">
<img src="/wikibg/logo.jpg" alt="网站Logo">
<span>万华镜</span>
</a>
<div class="nav-links">
<a href="首页" class="nav-link">
📚 首页
</a>
<a href="游戏攻略" class="nav-link">
📖 游戏攻略
</a>
<a href="棋子" class="nav-link">
⚔️ 棋子图鉴
</a>
<a href="天赋图鉴" class="nav-link">
🗺️ 天赋图鉴
</a>
<a href="装备图鉴" class="nav-link">
📊 装备图鉴
</a>
<a href="https://www.war3whj.top/war3wiki/moniqi/moniqi.html" class="nav-link">
📊 阵容模拟器
</a>
</div>
</div>
`;
// 将导航栏插入到 body 开头
$('body').prepend(navHtml);
// 滚动时添加效果(可选)
$(window).scroll(function() {
if ($(window).scrollTop() > 50) {
$('.fixed-top-nav').addClass('scrolled');
} else {
$('.fixed-top-nav').removeClass('scrolled');
}
});
}
});
$(function() {
// 确保页脚固定在底部
var footer = $('#footer, .mw-footer');
if (footer.length > 0) {
// 设置底部内边距避免内容被遮挡
var footerHeight = footer.outerHeight();
$('body').css('padding-bottom', footerHeight + 20 + 'px');
// 窗口大小改变时重新计算
$(window).resize(function() {
var newHeight = footer.outerHeight();
$('body').css('padding-bottom', newHeight + 20 + 'px');
});
}
});
$(function() {
// 为角色卡片添加悬停效果(可选,纯CSS已有,这里作为备用)
$('.character-card').hover(
function() { $(this).addClass('hover'); },
function() { $(this).removeClass('hover'); }
);
// 动态计算右侧边栏高度(可选,用于对齐)
function adjustSidebarHeight() {
var leftHeight = $('.custom-homepage .left-column').outerHeight();
var rightHeight = $('.custom-homepage .right-column').outerHeight();
if (rightHeight < leftHeight && $(window).width() > 768) {
$('.custom-homepage .right-column').css('min-height', leftHeight);
}
}
// 延迟执行,等待图片加载完成
setTimeout(adjustSidebarHeight, 500);
$(window).resize(adjustSidebarHeight);
});
/* 棋子筛选器(原有的锚点筛选) */
$(function() {
$('a[href^="#"]').click(function(e) {
e.preventDefault();
var filter = $(this).attr('href').substring(1);
if (filter === '全部') {
$('.role-card').show();
return;
}
$('.role-card').each(function() {
var text = $(this).text();
if (text.includes(filter)) {
$(this).show();
} else {
$(this).hide();
}
});
});
});
/* ========== 装备/棋子图鉴高级筛选器(TableFilter 类) ========== */
( function ( $, mw ) {
'use strict';
/**
* 表格筛选器类
*/
class TableFilter {
/**
* 创建一个新的 TableFilter 实例。
* @param {jQuery} $table - 要筛选的表格元素(jQuery 对象)。
* @param {Object} options - 配置选项。
* @param {string[]} options.columns - 要为其创建筛选器的列索引数组(从0开始)。
* @param {Object} options.labels - 筛选器列的显示名称。
* @param {number} options.headerRowIndex - 表头所在的行索引(默认为0)。
*/
constructor( $table, options ) {
this.$table = $table;
this.options = $.extend( {
columns: [],
labels: {},
headerRowIndex: 0
}, options );
// 存储每列的所有可能值
this.columnValues = {};
// 存储当前的筛选状态 { 列索引: 选中的值 }
this.currentFilters = {};
this.init();
}
/**
* 初始化筛选器:构建UI,解析表格数据,绑定事件。
*/
init() {
// 如果表格不存在或不是jQuery对象,则退出
if ( !this.$table || !this.$table.length ) {
return;
}
this.parseTableData();
this.buildUI();
this.bindEvents();
this.updateStats();
}
/**
* 解析表格数据,获取每列的所有唯一值。
*/
parseTableData() {
const self = this;
const $rows = this.$table.find( 'tr' ).slice( this.options.headerRowIndex + 1 ); // 跳过表头
this.options.columns.forEach( function( colIndex ) {
self.columnValues[ colIndex ] = new Set();
$rows.each( function() {
const $cell = $( this ).find( 'td, th' ).eq( colIndex );
if ( $cell.length ) {
const value = $.trim( $cell.text() );
if ( value ) {
self.columnValues[ colIndex ].add( value );
}
}
} );
// 将Set转换为数组,并按自然顺序排序
self.columnValues[ colIndex ] = Array.from( self.columnValues[ colIndex ] ).sort();
} );
}
/**
* 构建筛选器的UI界面。
*/
buildUI() {
const self = this;
const $container = $( '<div>' ).addClass( 'equipment-filter-container' );
this.options.columns.forEach( function( colIndex ) {
const $group = $( '<div>' ).addClass( 'equipment-filter-group' );
const labelText = self.options.labels[ colIndex ] || '筛选';
const $label = $( '<span>' ).addClass( 'equipment-filter-label' ).text( labelText + ':' );
$group.append( $label );
// 创建"全部"按钮
const $allBtn = $( '<span>' )
.addClass( 'equipment-filter-btn active' )
.attr( 'data-filter-col', colIndex )
.attr( 'data-filter-val', '' )
.text( '全部' );
$group.append( $allBtn );
// 为每个唯一值创建按钮
const values = self.columnValues[ colIndex ] || [];
values.forEach( function( val ) {
const $btn = $( '<span>' )
.addClass( 'equipment-filter-btn' )
.attr( 'data-filter-col', colIndex )
.attr( 'data-filter-val', val )
.text( val );
$group.append( $btn );
} );
$container.append( $group );
} );
// 创建底部工具栏(清除按钮 + 统计信息)
const $toolbar = $( '<div>' ).addClass( 'equipment-filter-group' );
const $resetBtn = $( '<span>' ).addClass( 'equipment-filter-reset' ).text( '清除所有筛选' );
const $stats = $( '<span>' ).addClass( 'equipment-filter-stat' );
$toolbar.append( $resetBtn, $stats );
$container.append( $toolbar );
// 将筛选器容器插入到表格之前
this.$table.before( $container );
// 保存UI元素的引用
this.$container = $container;
this.$stats = $stats;
this.$resetBtn = $resetBtn;
}
/**
* 绑定UI元素的事件。
*/
bindEvents() {
const self = this;
// 筛选按钮点击事件
this.$container.on( 'click', '.equipment-filter-btn', function() {
const $btn = $( this );
const col = $btn.data( 'filter-col' );
const val = $btn.data( 'filter-val' );
// 切换active类
$btn.closest( '.equipment-filter-group' ).find( '.equipment-filter-btn' ).removeClass( 'active' );
$btn.addClass( 'active' );
// 更新筛选状态
if ( val === '' ) {
delete self.currentFilters[ col ];
} else {
self.currentFilters[ col ] = val;
}
self.applyFilters();
} );
// 清除筛选按钮点击事件
this.$resetBtn.on( 'click', function() {
self.clearFilters();
} );
}
/**
* 应用当前的筛选条件,更新表格显示。
*/
applyFilters() {
const self = this;
const $rows = this.$table.find( 'tr' ).slice( this.options.headerRowIndex + 1 );
let visibleCount = 0;
$rows.each( function() {
const $row = $( this );
let showRow = true;
// 遍历当前所有的筛选条件
$.each( self.currentFilters, function( col, val ) {
const $cell = $row.find( 'td, th' ).eq( parseInt( col ) );
const cellValue = $.trim( $cell.text() );
if ( cellValue !== val ) {
showRow = false;
return false; // 跳出 each 循环
}
} );
if ( showRow ) {
$row.show();
visibleCount++;
} else {
$row.hide();
}
} );
this.updateStats( visibleCount );
}
/**
* 清除所有筛选条件,显示所有行。
*/
clearFilters() {
this.currentFilters = {};
this.$container.find( '.equipment-filter-btn' ).removeClass( 'active' );
// 激活"全部"按钮
this.$container.find( '.equipment-filter-btn[data-filter-val=""]' ).addClass( 'active' );
const $rows = this.$table.find( 'tr' ).slice( this.options.headerRowIndex + 1 );
$rows.show();
this.updateStats( $rows.length );
}
/**
* 更新统计信息(显示匹配行数)。
* @param {number} visibleCount - 当前可见的行数。
*/
updateStats( visibleCount ) {
if ( this.$stats ) {
const totalRows = this.$table.find( 'tr' ).length - ( this.options.headerRowIndex + 1 );
this.$stats.text( `显示 ${visibleCount} / ${totalRows} 项` );
}
}
}
/**
* 当页面加载完成后,初始化筛选器。
*/
$( document ).ready( function() {
// 检查当前页面是否包含需要筛选的表格
const $table = $( '.equipment-filter-target' );
if ( !$table.length ) {
return;
}
// ========== 筛选器配置(请根据你的表格列顺序修改) ==========
// 棋子图鉴表格字段顺序:图片, 图片文件名, 名称, _pageName, 稀有度, 费用, 定位, 羁绊
// 对应的列索引(从0开始):
// 0:图片 1:图片文件名 2:名称 3:_pageName 4:稀有度 5:费用 6:定位 7:羁绊
const filterConfig = {
columns: [ 4, 5, 6, 7 ], // 对稀有度(4)、费用(5)、定位(6)、羁绊(7)进行筛选
labels: {
4: '稀有度',
5: '费用',
6: '定位',
7: '羁绊'
},
headerRowIndex: 0 // 表头在第0行
};
// 实例化 TableFilter
new TableFilter( $table, filterConfig );
} );
} )( jQuery, mediaWiki );