Hitomi Reader Optimized Slim Navbar

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

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==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();
})();