全站通知:

MediaWiki:MultiCatalogue.js

来自黑神话:悟空WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-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); // 展开并选择该层
            });
        }
    });
}