MediaWiki:MultiCatalogue.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。
var catalogueMatrix = {}; // 创建一个空对象,用于存放根据相同 value 组合的信息
console.log('初始化'); // 初始化日志输出
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", Main);
} else {
Main();
}
function Main() {
console.log('初始化执行'); // 初始化日志输出
BuildHierarchy(); // 构建层次结构
BuildDirectory(); // 构建目录结构
AddFunction(); // 添加功能,如点击展开/收起目录
BindTabClickEvent(); // 绑定点击事件,用于处理 tab 切换
SetDefaultSelection(); // 设置默认选择项
console.log(catalogueMatrix); // 输出 catalogueMatrix 结果
}
function BuildHierarchy() {
function NewModule(endName) {
let newModule = {};
newModule.element = {}; // 创建一个空对象用于存放具体元素
newModule.endName = endName; // 记录拆分后的最后一个值
return newModule;
}
// 遍历所有类为 .pane-element 的元素
document.querySelectorAll('.pane-element').forEach(function (element) {
let id = element.id; // 获取元素的 id
let dataCatalogue = element.getAttribute('data-catalogue'); // 使用 getAttribute 方法获取元素的 data-catalogue 属性值
if (dataCatalogue) {
// 如果 data-catalogue 属性存在
let values = dataCatalogue.split('-'); // 根据 "-" 分割 data-catalogue 的值
let currentLevel = catalogueMatrix; // 从根开始构建嵌套的对象结构
let endName = values[values.length - 1]; // 获取拆分后的最后一个值
// 遍历分割后的 values
values.forEach(function (value, index) {
if (!currentLevel[value]) {
// 创建一个新模块,并将其赋值给当前层级
currentLevel[value] = NewModule(index === values.length - 1 ? endName : null);
}
// 如果当前是最后一级,则添加元素到 .element 中
if (index === values.length - 1) {
currentLevel[value].element[id] = { id: id, 'data-catalogue': dataCatalogue }; // 最后一级存放元素信息,包括 id 和 data-catalogue
} else {
currentLevel = currentLevel[value].element; // 进入下一层级的 element
}
});
}
});
}
function BuildDirectory() {
// 创建目录的递归函数
function buildDirectory(level) {
let ul = document.createElement('ul'); // 创建一个无序列表
for (let key in level) {
let li = document.createElement('li'); // 创建一个列表项
li.classList.add('tab-btn'); // 添加 tab-btn 类
// 创建公共的 dropDownWrap 和 wrapTitle
let dropDownWrap = document.createElement('div');
dropDownWrap.classList.add('catalogue-wrap');
let wrapTitle = document.createElement('div');
wrapTitle.classList.add('catalogue-title');
// 如果存在 endName,添加链接
if (level[key].endName) {
let link = document.createElement('a');
link.setAttribute('href', '#' + Object.values(level[key].element)[0].id); // 创建一个链接,指向第一个元素的 id
link.setAttribute('data-toggle', 'tab'); // 添加 data-toggle="tab" 属性
link.textContent = level[key].endName; // 链接的文本为 endName
wrapTitle.appendChild(link);
dropDownWrap.appendChild(wrapTitle);
li.appendChild(dropDownWrap); // 添加 dropDownWrap 到列表项
} else {
let wrapContent = document.createElement('div');
wrapContent.classList.add('catalogue-content');
wrapContent.style.display = 'none';
wrapContent.appendChild(buildDirectory(level[key].element)); // 递归构建子目录
let span = document.createElement('span');
span.textContent = key; // 创建一个 span 并添加 key 的文本
wrapTitle.appendChild(span); // 将 span 添加到 wrapTitle
dropDownWrap.appendChild(wrapTitle);
dropDownWrap.appendChild(wrapContent); // 先添加 wrapContent 再添加 wrapTitle
li.appendChild(dropDownWrap); // 添加 dropDownWrap 到列表项
}
ul.appendChild(li); // 添加列表项到无序列表
}
return ul; // 返回构建的无序列表
}
// 构建目录并添加到 .tab-nav 元素中
document.querySelector('.tab-nav').appendChild(buildDirectory(catalogueMatrix));
}
function AddFunction() {
// 绑定点击事件到 catalogue-title
document.querySelectorAll('.catalogue-title').forEach(function (title) {
title.addEventListener('click', function () {
// 找到同一层级下的 catalogue-content 元素
let cataContent = this.nextElementSibling;
if (cataContent && cataContent.classList.contains('catalogue-content')) {
// 获取元素的当前 display 属性
let displayStyle = window.getComputedStyle(cataContent, null).getPropertyValue('display');
// 切换 display 属性
if (displayStyle === 'none') {
cataContent.style.display = 'block';
// 为点击的 title 添加 title-active 类
this.classList.add('title-active');
} else {
cataContent.style.display = 'none';
// 移除 title-active 类
this.classList.remove('title-active');
}
} else {
// console.error('No corresponding .catalogue-content element found.');
}
});
});
}
function SetDefaultSelection() {
// 获取 .tab-group 元素及其 data-defselect 属性
var tabGroup = document.querySelector('.tab-group');
if (!tabGroup) return; // 如果没有找到 .tab-group 元素,直接返回
var defSelect = tabGroup.getAttribute('data-defselect'); // 获取 data-defselect 属性值
var found = false; // 标记是否找到匹配的 a 标签
document.querySelectorAll('.tab-btn').forEach(function(tabBtn) {
if (found) return; // 如果已找到匹配项,停止循环
var aTag = tabBtn.querySelector('.catalogue-title a');
var href = aTag ? aTag.getAttribute('href') : null;
var textContent = aTag ? aTag.textContent : '无文本';
if (href === '#' + defSelect) {
// 如果 a 标签的 href 与 data-defselect 值匹配
found = true; // 找到匹配的 a 标签
aTag.click(); // 触发点击事件,模拟用户点击
console.log(`匹配成功: ${defSelect} 与 ${href} 匹配。文本: ${textContent}`);
return; // 结束循环
} else {
console.log(`未匹配: ${defSelect} 与 ${href} 不匹配。文本: ${textContent}`);
}
});
if (!found) {
// 如果没有找到匹配的 a 标签,默认选择第一个 a 标签
var firstATag = document.querySelector('.tab-btn .catalogue-title a');
if (firstATag) {
firstATag.click(); // 触发点击事件,模拟用户点击
console.log(`未找到匹配项,选择了第一个 a 标签: ${firstATag.getAttribute('href')}。文本: ${firstATag.textContent}`);
}
}
}
function ExpandToSelection(selectedTabBtn) {
// 展开选中的目录层级,并关闭其他层级
var parent = selectedTabBtn.closest('.catalogue-wrap');
while (parent) {
var cataContent = parent.querySelector('.catalogue-content');
if (cataContent) {
cataContent.style.display = 'block';
}
var title = parent.querySelector('.catalogue-title');
if (title) {
title.classList.add('title-active');
}
parent = parent.parentElement.closest('.catalogue-wrap');
}
// 关闭其他未选中的层级
document.querySelectorAll('.catalogue-content').forEach(function(content) {
if (!content.contains(selectedTabBtn)) {
content.style.display = 'none';
}
});
document.querySelectorAll('.catalogue-title').forEach(function(title) {
if (!title.contains(selectedTabBtn)) {
title.classList.remove('title-active');
}
});
}
function BindTabClickEvent() {
// 遍历所有 .tab-btn 元素,为其中的 .catalogue-title a 绑定点击事件
document.querySelectorAll('.tab-btn').forEach(function(tabBtn) {
var aTag = tabBtn.querySelector('.catalogue-title a');
if (aTag) {
aTag.addEventListener('click', function() {
// 移除所有 .tab-btn 元素中的 .active 类
document.querySelectorAll('.tab-btn.active').forEach(function(activeBtn) {
if (activeBtn !== tabBtn) {
activeBtn.classList.remove('active');
}
});
// 为当前点击的 .tab-btn 元素添加 .active 类
tabBtn.classList.add('active');
ExpandToSelection(tabBtn); // 展开并选择该层
});
}
});
}