Hitomi Reader Optimized Slim Navbar

MutationObserverを使用して低負荷でテキストを消去し、1行を維持する

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Hitomi Reader Optimized Slim Navbar
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  MutationObserverを使用して低負荷でテキストを消去し、1行を維持する
// @author       Your Name
// @match        https://hitomi.la/reader/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 1. スタイル注入(メディアクエリ上書きと1行固定)
    const style = document.createElement('style');
    style.innerHTML = `
        /* 画面幅に関わらず強制表示 */
        @media (max-width: 979px) {
            .nav-collapse, .nav-collapse.collapse {
                display: flex !important;
                height: 24px !important;
                overflow: visible !important;
                visibility: visible !important;
            }
            .navbar .brand { display: block !important; }
        }

        /* ナビバー全体の高さを24pxに固定 */
        .navbar, .navbar-inner, .navbar-inner .container {
            min-height: 24px !important;
            height: 24px !important;
            display: flex !important;
            flex-direction: row !important;
            flex-wrap: nowrap !important;
            align-items: center !important;
            padding: 0 5px !important;
            margin: 0 !important;
        }

        .navbar .brand {
            padding: 0 8px 0 0 !important;
            margin: 0 !important;
            font-size: 12px !important;
            line-height: 24px !important;
            float: none !important;
        }

        .nav-collapse { display: flex !important; float: none !important; }
        .navbar-nav { display: flex !important; flex-direction: row !important; margin: 0 !important; }
        .navbar-nav > li { float: none !important; }

        /* テキストを見えなくする(CSS側でも念押し) */
        .navbar-nav > li > a {
            font-size: 0 !important;
            padding: 0 4px !important;
            height: 24px !important;
            display: flex !important;
            align-items: center !important;
            text-indent: -9999px; /* テキストを画面外へ */
        }
        .navbar-nav > li > a i {
            font-size: 12px !important;
            text-indent: 0; /* アイコンは戻す */
            display: inline-block !important;
        }

        .navbar-search.pull-right {
            margin-left: 5px !important;
            display: flex !important;
            align-items: center !important;
            float: none !important;
        }

        .input-medium, select#single-page-select {
            height: 19px !important;
            line-height: 1 !important;
            padding: 0 1px !important;
            font-size: 10px !important;
            width: auto !important;
            min-width: 45px !important;
            background-color: #222 !important;
            color: #ddd !important;
            border: 1px solid #444 !important;
        }

        .btn-navbar { display: none !important; }
    `;
    document.head.appendChild(style);

    // 2. テキストノードを消去する関数
    const cleanTextNodes = () => {
        const links = document.querySelectorAll('.navbar-nav > li > a');
        links.forEach(link => {
            for (let node of link.childNodes) {
                if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "") {
                    node.textContent = "";
                }
            }
        });
    };

    // 3. MutationObserverによる低負荷な監視
    // サイトのJSがHTMLを書き換えたときだけ cleanTextNodes を実行する
    const observer = new MutationObserver(() => {
        observer.disconnect(); // ループ防止のため一時停止
        cleanTextNodes();
        observer.observe(document.querySelector('.navbar-inner'), { childList: true, subtree: true });
    });

    // 監視開始
    const target = document.querySelector('.navbar-inner');
    if (target) {
        observer.observe(target, { childList: true, subtree: true });
    }

    // 初回実行
    cleanTextNodes();
})();