洛谷题目背景隐藏和显示 v1.2

v1.2 版本特性:

  • 将“题目背景”修改为一个链接按钮,样式不变,单击按钮可以隐藏题目背景,再次单击显示
  • 可以记忆每道题的题目背景是否显示(默认显示)
  • 适配新前端
  • 暂不兼容 IDE 模式,未来会做
  • 洛谷小改了一下新前端代码,v1.1 做了适配
  • 修复了没有题目背景时会折叠题目描述的 BUG

效果展示:

image

(此部分内容前置以方便搜索引擎获取网页简介。)


众所周知,Ynoi 的题一般都有一个巨长但是没什么用的背景。本人刷题时深受其害:读题的时候需要不停地向下翻过十几张图片和莫名其妙的文字,来看题目描述和数据范围;再向上翻过十几张图片和不知所云的文字,来看题目难度和时空限制。而且旁边有人在的时候刷题,题目上全是各种奇奇怪怪的图片,真的很尴尬。

因此,我用 DeepSeek-R1 写了一个 TamperMonkey 脚本的框架,然后用我不多的JS知识微调了一下,诞生了这份可以选择题目背景隐藏和显示的脚本。


v1.2 代码:

// ==UserScript==
// @name         洛谷题目背景隐藏和显示
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  点击切换题目背景显示状态,并保留记忆功能
// @author       Jerrycyx & DeepSeek-R1
// @match        https://www.luogu.com.cn/problem/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 等待目标元素加载
    const readyCheck = setInterval(() => {
        const h2Elements = document.querySelectorAll('#app > div.main-container > main > div > div > div.main > div > h2');

        let targetH2 = null;
        let targetDiv = null;

        // 遍历所有h2元素,寻找textContent为"题目背景"的第一个元素
        for (let i = 0; i < h2Elements.length; i++) {
            if (h2Elements[i].textContent.trim() === '题目背景') {
                targetH2 = h2Elements[i];

                // 获取父节点下的下一个兄弟元素节点
                let nextSibling = targetH2.nextElementSibling;

                // 检查是否是div元素
                if (nextSibling && nextSibling.tagName === 'DIV') {
                    targetDiv = nextSibling;
                }
                break; // 找到第一个匹配项后立即退出循环
            }
        }

        if (targetH2 && targetDiv) {
            clearInterval(readyCheck);
            initializeToggleSystem(targetH2, targetDiv);
        }
    }, 100);

    function initializeToggleSystem(h2Element, contentDiv) {
        // 创建包裹链接
        const toggleLink = document.createElement('a');
        toggleLink.href = 'javascript:void 0';
        toggleLink.style.display = 'block';
        toggleLink.style.width = 'fit-content';
        h2Element.parentNode.replaceChild(toggleLink, h2Element);
        toggleLink.appendChild(h2Element);

        // 获取题目唯一标识
        const problemId = window.location.pathname.split('/problem/')[1].split('/')[0];

        // 初始化状态
        const savedState = localStorage.getItem(`luoguToggleState_${problemId}`);
        const initialState = savedState === 'hidden';

        // 初始状态设置
        if (initialState) {
            contentDiv.style.display = 'none';
            insertStatusNotice(contentDiv);
            updateToggleText(toggleLink, false);
        } else {
            updateToggleText(toggleLink, true);
        }

        // 点击事件处理
        toggleLink.addEventListener('click', function () {
            const currentState = localStorage.getItem(`luoguToggleState_${problemId}`) === 'hidden';
            const newState = !currentState;

            contentDiv.style.display = newState ? 'none' : '';
            updateToggleText(toggleLink, !newState);
            localStorage.setItem(`luoguToggleState_${problemId}`, newState ? 'hidden' : 'visible');

            // 管理状态提示
            const existingNotice = contentDiv.nextElementSibling?.classList?.contains('status-notice');
            if (newState && !existingNotice) {
                insertStatusNotice(contentDiv);
            } else if (!newState && existingNotice) {
                contentDiv.nextElementSibling.remove();
            }
        });

        // 辅助函数
        function insertStatusNotice(referenceNode) {
            const notice = document.createElement('p');
            notice.textContent = '(已隐藏)';
            notice.className = 'status-notice';
            referenceNode.insertAdjacentElement('afterend', notice);
        }

        function updateToggleText(linkElement, showText) {
            linkElement.querySelector('h2').textContent =
                `题目背景 - ${showText ? '显示' : '隐藏'}`;
        }
    }
})();
posted @ 2025-03-24 19:36  Jerrycyx  阅读(85)  评论(0)    收藏  举报